自动合成后,getter和setter方法的主体是什么样的?
从官方文档到目前为止我发现只推荐了实现技术,但没有说明编译器在合成过程中使用了哪些技术:http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW5
某些技术建议包含autorelease
消息的实现,这对于多线程编程来说并不十分安全。我只是想知道自动生成的代码是否跟随一些提议的实现。
例如:
·H
@interface AClass: NSObject{}
@property (nonatomic, retain) AnotherClass *aProp;
@end
的.m
@implementation AClass
@synthesize aProp
-(id) init {
if ((self = [super init])) {
self.aProp = [[AnotherClass alloc] init]; // setter invocation
}
return self;
}
-(AnotherClass *) aMethod {
return self.aProp; // getter invocation
}
@end
编译器生成的aProp
的等效访问者代码片段是什么?
-(AnotherClass *) aProp {
// getter body
}
-(void) setAProp: (AnotherClass *) {
// setter body
}
答案 0 :(得分:8)
将属性声明为nonatomic
时,您将获得以下内容:
// .h
@property (nonatomic, retain) id ivar;
// .m
- (id)ivar {
return ivar;
}
- (void)setIvar:(id)newValue {
if (ivar != newValue) { // this check is mandatory
[ivar release];
ivar = [newValue retain];
}
}
请注意支票ivar != newValue
。如果不存在,则可以在release
之后取消分配ivar,并且以下retain
将导致内存访问错误。
当您使用copy
声明属性时,代码看起来几乎相同,retain
替换为copy
。
对于assign
,它甚至更简单:
- (void)setIvar:(id)newValue {
ivar = newValue;
}
现在,当您将属性声明为atomic
(这是默认属性)时,事情会变得稍微复杂一些。苹果公司的一位工程师在开发论坛上发布了一个与下面类似的片段:
- (id)ivar {
@synchronized (self) {
return [[self->ivar retain] autorelease];
}
}
- (void)setIvar:(id)newValue {
@synchronized (self) {
if (newValue != self->ivar) {
[self->ivar release];
self->ivar = newValue;
[self->ivar retain];
}
}
}
请注意两种方法中的@synchronized
块和getter中的其他retain-autorelease
。这两件事都可以确保您获得之前的值(保留和自动释放)或者在您尝试阅读时由某个线程更改值的情况下获得新值。
答案 1 :(得分:0)
这取决于您设置的属性,例如使用RETAIN属性...
- (void)setAProp:(AnotherClass *)value {
[aProp release];
aProp = value;
[aProp retain];
}
对于ASSIGN属性....
- (void)setAProp:(AnotherClass *)value {
aProp = value;
}
对于COPY属性(与NSString一起使用)......
- (void)setAProp:(AnotherClass *)value {
aProp = [value copy];
}