2012-07-07 67 views
0

我目前正在为iPhone开发我的第一个应用程序,我已经差不多完成了,但我遇到了内存管理等问题。请记住,我对Java很好,我只学习了Objective C约4天。Objective C内存问题

所以,确切的问题在于这个领域(在星号之间)。 注意:如果重要的话,所有的代码都在一个大的游戏循环中。

else 
     { 
      *********************************** 
      NSString *rand = [NSString stringWithFormat:@"%@", randNumberS]; 
      while(lastTime + interval >= currentTime) 
      { 
     !!!!!!!!!NSString *user = [NSString stringWithFormat:@"%@", userText]; 
        if([user isEqualToString: rand]) 
        { 
      *********************************** 
         score += 10; 
         randNumberS = nil; 
         timeToGenerateNum = true; 
         bottomClear = true; 
         break; 
        } 
        else 
        { 

         //NSLog(@"%@ != %@, %i", userText, randNumberS, score); 
        } 

      } 
      NSLog(@"Game Over! Your score was %i!", score); 
     } 
    } 

每次我才启用僵尸我跑了(注:该代码跑了几秒钟的BTW),我得到了一个Thread 6: Program received signal: "EXC_BAD_ACCESS"在标有行“!”。启用僵尸后,它会运行几秒钟,然后停止工作,并在控制台中显示消息-[CFString respondsToSelector:]: message sent to deallocated instance 0x11168440。它也标记与“!”相同的行我注意到这两个问题,他们都指向糟糕的内存管理,我试图释放NSString对象,但我的程序不会让我释放对象(注意:我得到这个错误信息"release" is unavailable: not available in automatic reference counting mode)。

任何帮助将不胜感激,谢谢!

编辑:

userText以各种数量的方法中使用,但主要是在这一个。

-(IBAction)button1Clicked:(id)sender 
{  
if(userText == nil) 
{ 
    userText = [NSString stringWithFormat:@"%i", 1]; 
} 
else 
{ 
    userText = [NSString stringWithFormat:@"%@%i",userText , 1]; 
} 
bottomLabel.text = userText; 
NSLog(@"Test 1"); 
} 
+0

它看起来像在userText的实例不再你身边,你可以显示如该被初始化,以及它是如何在这个代码的其他地方处理? – 2012-07-07 16:41:04

回答

1

userText变量是不是有效的对象,这是你的错误消息表示。通常,当您尝试使用指向不再存在的指针时,EXC_BAD_ACCESS会发生。然后启用僵尸,消息更加清晰,userText曾经是一个字符串,但已被释放。

编辑:

如果userText是一个实例变量,建议使用属性,然后点表示法。某处有一个@interface部分,其中声明了userText。它应该这个样子:

@property (nonatomic, strong) NSString *userText; 

然后在@implementaiton区域,像这样:

@synthesize userText = _userText; 

这些,在一起,使点符号可用,那么你应该使用 self.userText访问它到处(除定制存取):

self.userText = @"something"; 
NSString *something = self.userText; 
+0

然后我如何重新分配它? – HDAViiRuS 2012-07-07 16:47:58

+0

你不重新分配它们,你用“强”(拥有)引用保留它们。 – 2012-07-07 16:51:50

+0

@ranReloaded你能指定我怎么做,谢谢! – HDAViiRuS 2012-07-07 16:54:47

1

您正在使用ARC,因此您将无法释放对象,但是如果您想释放它们,则可以将它们设置为零。

相反,您可以使用不需要保留的变量,也可以对那些想要保留的变量使用较强的修饰符。

如果您只是在学习obj-c,我会强烈建议禁用ARC,以便全面了解objective-c的工作方式以及为什么ARC现在是来自Apple的建议。

+0

谢谢!但是你知道我的问题的解决方案吗? – HDAViiRuS 2012-07-07 16:50:14

+1

我确实在你的头文件中使用了一个属性,用强限定符来解决你的问题。 – 2012-07-07 16:54:51

0

解决这类问题的常用方法是启用NSZombies。当您以比友善的方式发送消息到释放对象时,这会标记出来,而不是抛出此异常。

此外,由于这些调用是编译器在构建时添加的,所以还不能使用retainreleaseautorelease

有一些奇怪的建设与要创建的randuser NSString的方式,但不知道什么randNumberSuserText是我不能帮助更多。

最后,由于您是Cocoa和Objective-C的新成员,有Apple的Coding Style Guide,我写了一个coding conventions指南。

编写Cocoa时有一些约定,使其他开发人员更容易阅读您的代码。

+0

@Abizem谢谢,我会考虑两个! – HDAViiRuS 2012-07-07 17:09:55

1

在仪器下的模拟器上运行您的应用程序(使用Xcode的Product> Profile菜单项)。选择僵尸工具。当乐器由于僵尸参考而停止您的应用程序时,您可以在详细信息面板(“乐器”窗口的底部)中深入查看僵尸对象上的保留和释放历史记录。您可以通过打开扩展详细信息面板(“仪器”窗口的右侧)来查看每个保留和释放的堆栈跟踪。

这应该可以帮助你追踪为什么你的僵尸对象在你预期之前被释放。

链接与其他指导:

http://www.markj.net/iphone-memory-debug-nszombie/

http://www.dimzzy.com/blog/2011/02/hunting-down-zombies-in-ios-apps/