在属性name
的getter函数(自动生成)中,对象是否按如下方式返回?
[self.name autorelease];
return self.name;
在setter函数(也是自动生成的)中,是retain
ed对象autorelease
d? -
- (void) setName : (NSString *) someString {
[someString retain];
[name release];
name = someString;
/* [someString autorelease]; */ // performed internally?
}
#import<Foundation/Foundation.h>
@interface Dog : NSObject
{@private NSString * name;}
@property (nonatomic,retain) NSString * name;
@end
@implementation Dog
@synthesize name;
- (id) init {
self = [super init];
if(self) {}
return self;
}
@end
int main(int argc, char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Dog * d = [[Dog alloc] init];
[d setName:@"Scooby"];
NSLog(@"Dog's name is: %@",[d name]);
[d release];
[pool drain];
return 0;
}
答案 0 :(得分:3)
没有。您要求的自动释放将释放名称并导致访问冲突,因为名称中的对象不会被保留。如果getter在返回之前保留了对象,则它可以返回一个自动释放的对象:return [[name retain] autorelease] ;.可能需要这样做才能支持从多个线程进行访问,但在这种情况下,某些线程同步需要在getter和setter中。
为了使您的代码在非ARC中正确,它需要一个释放名称的dealloc方法。
- (void)dealloc
{
[name release];
[super dealloc];
}
对自动生成的代码here的主题进行了一些讨论。
答案 1 :(得分:2)
回答你的两个问题:
getter不应该autorelease
该对象。
setter不应autorelease
someString
指向的新值对象。
autorelease
实际上是延迟release
,因此不适合getter或setter这样做。当然,setter会release
旧对象,但肯定不应该对新对象进行autorelease
。
顺便提一下,最后三个观察结果:
除非有一些迫切的需要,否则你不应该写自己的定位器和吸气剂。如果你只是想了解他们正在做什么,那很好,但在实践中,我们很少编写自己的访问方法。
此外,我衷心鼓励您使用ARC(如果可以的话)。
如果出于某种原因使用Xcode并使用手动引用计数,请务必通过静态分析器运行代码(Xcode“Product”菜单上的“Analyze”),因为它会指出许多常规错误。 autorelease
。
如果在GNUStep中使用gcc,您的Dog
类可能如下所示:
@interface Dog : NSObject
{
NSString *_name;
}
@property (nonatomic, copy) NSString *name;
@end
@implementation Dog
@synthesize name = _name;
- (id)init
{
self = [super init];
if (self) {
_name = nil;
}
return self;
}
- (void)dealloc
{
[_name release];
[super dealloc];
}
@end
注意,没有定义访问器方法(它们是为我合成的)。
虽然gcc不支持它,但如果您使用的是较新的编译器,则可以省略ivar声明和@synthesize
行:
@interface Dog : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation Dog
- (id)init
{
self = [super init];
if (self) {
_name = nil;
}
return self;
}
- (void)dealloc
{
[_name release];
[super dealloc];
}
@end
或者如果使用ARC,您甚至可以省略init
方法(因为ARC将对象初始化为nil
)和dealloc
方法(因为ARC显然会自动释放对象):
@interface Dog : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation Dog
@end