这是来自内存管理编程指南:
技术 1
在技术 1 中,getter 返回的值在调用范围内自动释放:
- (NSString*) title {
return [[title retain] autorelease];
}
- (void) setTitle: (NSString*) newTitle {
if (title != newTitle) {
[title release];
title = [newTitle retain]; // Or copy, depending on your needs.
}
}
因为从 get 访问器返回的对象是在当前范围内自动释放的,所以如果属性值发生更改,它仍然有效。这使得访问器更加健壮,但代价是额外的开销。如果您希望您的 getter 方法被频繁调用,那么保留和自动释放对象的额外成本可能不值得性能成本。
技巧 2
与技术 1 一样,技术 2 也使用自动释放技术,但这次在 setter 方法中使用:
- (NSString*) title {
return title;
}
- (void) setTitle: (NSString*) newTitle {
[title autorelease];
title = [newTitle retain]; // Or copy, depending on your needs.
}
在 getter 比 setter 更频繁地调用的情况下,技术 2 的性能明显优于技术 1。
技术 3
技术 3 完全避免使用自动释放:
- (NSString*) title {
return title;
}
- (void) setTitle: (NSString*) newTitle {
if (newTitle != title) {
[title release];
title = [newTitle retain]; // Or copy, depending on your needs.
}
}
技术 3 使用的方法适用于经常调用的 getter 和 setter 方法。它也适用于不想延长其值的生命周期的对象,例如集合类。它的缺点是旧值可能会立即被释放(如果没有其他所有者),如果另一个对象维护对它的非拥有引用,这将导致问题。例如:
NSString *oldTitle = [anObject title];
[anObject setTitle:@"New Title"];
NSLog(@"Old title was: %@", oldTitle);
如果 anObject 是唯一拥有原始标题字符串的对象,则在设置新标题后,该字符串将被释放。日志语句将导致崩溃,因为 oldTitle 是一个已释放的对象。
编辑:基本上保留然后自动释放的目的是确保如果在调用范围有机会保留它之前更改了属性值,则该对象不会被释放。除非您有异步代码,否则这通常不是问题。在大多数情况下,- (Weapon *)myWeapon { return myWeapon; } 很好(而且速度更快)。