我弄乱了在方法中创建对象并将其返回给变量。和this post中一样,我知道在这种情况下我应该自动释放一个对象,但是当我这样做时,它会崩溃。
我编写了一个创建图像数组的方法,并返回此数组。它看起来像这样:
- (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
for (int i = 1; i <= numberFrames; ++i) {
NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
[imageArray addObject:[UIImage imageNamed:imageName]];
[imageName release];
}
return imageArray;
}
我称之为:
NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
[imageArray release];
但是,当我运行构建分析器时,它会进行编译,但会出现以下抱怨:
在第109行分配的物体的潜在泄漏 1.方法返回一个具有+1保留计数(拥有引用)的Objective-C对象 2.对象作为拥有引用返回给调用者(单个保留计数转移给调用者)
中给出的命名约定规则
3.在第109行分配的对象是从名称('createImagesFor:withFrames:')不包含'copy'或以'new'或'alloc'开头的方法返回的。这违反了“Cocoa内存管理指南”(对象泄露)
我已经查看了memory management文档,但除了自动释放变量(崩溃了)之外,我不知道我哪里出错了。这是我自动释放它的方式:
NSMutableArray *imageArray = [[[NSMutableArray alloc] initWithCapacity:numberFrames]autorelease];
我尝试将* imageArray保留为suggested here,如下所示:
NSMutableArray *imageArray;
[imageArray retain];
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
[imageArray release];
但这也崩溃了。
分析器建议我将方法的名称更改为'newCreateImagesFor:withFrames:'但我不知道这是如何修复的?
感谢您的帮助。
迈克尔答案 0 :(得分:5)
您应该将第一个代码块的最后一行更改为return [imageArray autorelease]
并在第二部分中删除该版本(通常不需要释放方法调用返回的对象)。这就是分析仪投诉的内容。但是,我不明白为什么它会导致崩溃。
如何定义animationImages
属性?这可能是你问题的根源。
答案 1 :(得分:2)
- (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
for (int i = 1; i <= numberFrames; ++i) {
NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
[imageArray addObject:[UIImage imageNamed:imageName]];
[imageName release];
}
return imageArray;
}
返回一个保留计数为+1但未自动释放的imageArray
对象,clang静态分析器会警告你这一点,这与命名约定有关,因为你的方法没有被命名与newImagesFor...
或allocImagesFor...
或copyImagesFor...
相似。
NSMutableArray *imageArray;
[imageArray retain];
// sending message to nil, does nothing
imageArray = [self createImagesFor:@"jumping" withFrames:2];
// imageArray has a retain count of 1
// and it is an autoreleased object
self.animationImages = imageArray;
[imageArray release];
// retain count = 0, will be dealloc'd,
// however it is already in the autorelease pool,
// it will be over-released at the end of current event run loop
当您声明imageArray
时,它是指向类NSMutableArray
的空指针,在您的情况retain
中向Objective-C中的空指针发送消息是可能的,并且不会抛出异常。
如果使用属性访问器来缓存imageArray
对象,则应声明属性访问器以保留您指定的对象
@property (retain) NSMutableArray *imageArray;
既然你的方法正确地返回了一个自动释放的imageArray
,并且你有一个正确的属性访问器,那么所需要的只是
NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;