以下两个陈述都有效。但第二个声明给了我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
?
非常感谢。
答案 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内存管理概念时,它会对您有所帮助。