0

我目前正在为 iPhone 开发我的第一个应用程序,我几乎完成了,但我遇到了内存管理等问题。请记住,我对 java 非常擅长,而且我只学习了 Objective C 大约 4 天。

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

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);
        }
    }

每次我在启用僵尸之前运行(注意:代码运行了几秒钟顺便说一句),我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");
}
4

4 回答 4

1

userText变量不是有效对象,这是您的错误消息所指示的。一般来说,EXC_BAD_ACCESS 发生在您尝试使用指向不再存在的东西的指针时。然后在启用 Zombies 的情况下,消息更加清晰,userText以前是一个字符串,但已被释放。

编辑:

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

@property (nonatomic, strong) NSString *userText;

然后在@implementaiton 区域中,如下所示:

@synthesize userText = _userText;

这些一起使点符号可用,然后您应该使用 self.userText 在任何地方访问它(自定义访问器除外):

self.userText = @"something";
NSString *something = self.userText;
于 2012-07-07T16:42:56.970 回答
1

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

相反,您可以对不需要保留的变量使用弱修饰符,或者对打算保留的变量使用强修饰符。

如果您只是学习 obj-c,我强烈建议您禁用 ARC,这样您就可以全面了解 Objective-c 的工作原理以及为什么 ARC 现在是 Apple 的推荐。

于 2012-07-07T16:48:24.813 回答
1

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

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

带有额外指导的链接:

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

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

于 2012-07-07T17:05:12.263 回答
0

解决这类问题的常用方法是启用 NSZombies。当您以比抛出此异常更友好的方式向已释放对象发送消息时,这将被标记。

此外,对于 ARC,您不能使用retainrelease或者autorelease因为编译器在构建时添加了这些调用。

rand您创建和NSStrings的方式有一些奇怪的结构user,但是在不知道什么randNumberSuserText是什么的情况下,我无能为力。

最后,由于您是 Cocoa 和 Objective-C 的新手;有苹果的编码风格指南,我写了一个编码约定指南。

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

于 2012-07-07T16:54:20.067 回答