imageWithContentsOfFile导致EXC_BAD_ACCESS

时间:2011-12-29 19:02:58

标签: ios cocoa-touch image

以下两个陈述都有效。但第二个声明给了我EXC_BAD_ACCESS。

    UIImageWriteToSavedPhotosAlbum([UIImage imageNamed:photoFilenameNoPath], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

    UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:filenameWithPath], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

我将其追溯到[image autorelease]

    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

        NSString *alertTitle;
        NSString *alertMessage;

        if (error == nil) {
            // Display UIAlertView to tell user that photo have been saved
            alertTitle = @"Photo Saved";
            alertMessage = @"";
        }
        else {
            // Display UIAlertView with error string to tell user that photo have NOT been saved
            alertTitle = @"Photo Not Saved";
            alertMessage = [NSString stringWithFormat:@"ERROR SAVING:%@",[error localizedDescription]];
        }

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle message:alertMessage delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];                                                                                                              
        [alert show];
        [alert release];        

        [image autorelease];
    }

我需要使用imageWithContentsOfFile,因为我的一些文件位于Documents文件夹中,有些文件位于主包中。

如果我使用image代替imageWithContentsOfFile,任何人都可以帮助解释为什么我不需要发布imageNamed

非常感谢。

2 个答案:

答案 0 :(得分:0)

您无需在代码中放置[image autorelease]。在Cocoa框架中,只有在键入'alloc'或'retain'时才调用release或autorelease,否则只保留对象。您使用的两种UIImage方法都没有调用alloc或retain,因此您不需要自动(自动)释放它们。

返回新对象的Convinience类方法总是自动释放,稍后释放,如果你想让它们不被释放,请调用retain。之后,您必须调用'release'或'autorelease'来释放对象。

如果你没有释放对象,它将留在占用空间的内存中。对于iOS,我建议您尽量避免使用自动释放,因为目标c没有交换空间和有限的内存。

答案 1 :(得分:0)

第二个陈述是有效的,因为你很幸运(因为image上有一个额外的保留,这是由你的代码之外的东西造成的。)

两个函数imageNamed:imageWithContentsOfFile:中没有一个暗示您拥有返回的image对象的名称。这意味着您不必对其进行发布。

  

您拥有自己创建的任何对象   您可以使用名称以“ alloc ”,“ new ”,“复制”或“ mutableCopy”开头的方法创建对象“(例如,alloc,newObject或mutableCopy)。

遵循此规则,imageWithContentsOfFile:imageNamed:都不会授予您对已创建对象的所有权。你不拥有它,你没有(自动) - 发布它。

要了解更多信息,请转到Apple Memory Management Guide


我很惊讶CLANG没有发现这个错误。在项目设置中验证运行静态分析器是否已打开。在尝试理解Cocoa内存管理概念时,它会对您有所帮助。