在类方法中自动释放NSString导致iOS中的应用程序崩溃

时间:2011-07-28 05:17:47

标签: objective-c class memory methods

我收到的错误如下:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil); //breakpoint that says Thread 1: Program Received Signal: "EXC_BAD_ACCESS".
    [pool release];
    return retVal;
}

我的两个问题可以在这篇文章的底部找到:)

我目前正在为iOS编程课程完成一项任务,并且遇到了一个障碍。

我找到了一个修复程序,如下所示,但对我来说没有意义。看看:

@implementation MyClass

// This class method takes an (NSMutableArray *) and returns an NSString with its contents printed out.
+ (NSString *)myString:(NSMutableArray)anArray
{
    // NSString *myString = [[NSString alloc] init]; OLD CODE THAT CAUSES MEMORY LEAK
NSString *myString = [[[NSString alloc] init] autorelease]; //NEW CODE THAT RELEASES FIRST ALLOCATION OF myString WHEN THE FIRST stringByAppendingFormat: IS CALLED
    NSString *vp = VARIABLE_PREFIX; //#defined above to be @"%

    for (id object in anArray) {
        if ([object isKindOfClass:[NSString class]]) {
            if ([object hasPrefix:vp]) {
                myString = [myString stringByAppendingFormat:@"%@",[object substringFromIndex:1]];
            }else{
                myString = [myString stringByAppendingFormat:@"%@",object];
            }
        }else if ([object isKindOfClass:[NSNumber class]]) {
            myString = [myString stringByAppendingFormat:@"%@",object];
        }
    }

    return myString; //shouldn't I autorelease myString right before this line? NO NOT ANY MORE. THIS myString IS NOT THE ORIGINAL THAT I alloc-init, BUT AN AUTORELEASED OBJECT RETURNED BY THE stringByAppendingFormat: message.
    }

当我尝试发送消息[myString autorelease];时,程序因上述错误而崩溃。它现在正常工作,如上所示,但我不明白为什么。

每当我发送包含“魔语”alloc, init, copy的消息时,我都要拨打release,不是吗?或者Class方法中的规则是不同的(Class本身可以拥有一个文件吗?)。我不会在调用此文件的对象中调用retain

以下是我的两个问题:

  1. 当我尝试使用theDescription发布autorelease时,为什么会崩溃?

  2. 我的代码是否会造成内存泄漏?

  3. 这是关于堆栈溢出的第一个问题!谢谢你的帮助!

2 个答案:

答案 0 :(得分:2)

当我尝试使用autorelease发布描述时,为什么会崩溃?

假设您的意思是myString,它会崩溃,因为myString已经自动释放了。你通过调用-stringByAppendingFormat:得到它,它返回一个自动释放的字符串。现在,你可能会想:“但是我通过调用+ alloc来创建它,所以我应该释放它。”这是真的,但NSStrings是不可变的,当你调用-stringByAppendingFormat:时,你会得到一个不同的字符串,并且该字符串是自动释放的。第二次自动释放它是一个错误。

我的代码是否会造成内存泄漏?

是的,但不是真的。 “泄露”对象是您在开头分配的空字符串。你永远不会释放那个字符串,所以你有泄漏。但是,NSString显然已经过优化,因此[[NSString alloc] init]返回一个单例,因此在这种特殊情况下,不释放空字符串没有任何区别。分配给myString的其他字符串都是自动释放的,因此这些对象都不会泄露。

答案 1 :(得分:0)

当我尝试使用

发布描述时,为什么会崩溃?

使用更新的代码,问题是ypu使用已返回autoreleases对象的methid重新分配指向myString的指针:stringbyappending,因此如果你在这个已经将要自动释放的对象上调用autorelease,我将崩溃。

另外,当使用stringbyappendingstring重新分配ypu时,alloc init中的第一个appugnment会给内存泄漏,因为你丢失了对使用alloc init的先前创建的字符串的引用,因此你永远无法释放它。

很抱歉我的iPhone上的格式为atm =)