为声明的属性合成了哪些等效代码?

发布于 2024-10-24 23:57:33 字数 1187 浏览 1 评论 0原文

自动合成后的 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
}

How exactly getter and setter methods body looks like after they have been automatically synthesized ?

From official documentation I found so far only recommended implementation techniques, however no word about which of them used by compiler during synthesizing process: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW5

Some techniques recommends implementations containing autorelease message, which is not quite secure for multithreaded programming. I'm just wonder if auto-generated code follows to some of the proposed implementations.


For example:

.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

What are equivalent accessors code snippets for aProp generated by compiler ?

-(AnotherClass *) aProp {
    // getter body
}

-(void) setAProp: (AnotherClass *) {
    // setter body
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余罪 2024-10-31 23:57:33

将属性声明为 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。如果不存在,ivar 可能会在release 后被释放,并且下面的retain 将导致内存访问错误。

当您使用 copy 声明属性时,代码看起来几乎相同,只是将 retain 替换为 copy

对于分配,它甚至更简单:

- (void)setIvar:(id)newValue {
    ivar = newValue;
}

现在,当您将属性声明为原子(这是默认值)时,事情会变得稍微复杂一些。 Apple 的一位工程师在开发论坛上发布了类似于下面的代码片段:

- (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 。这两件事都确保您将获得前一个值(保留和自动释放)或一个新值,以防您在尝试读取该值时某个线程更改了该值。

When declaring a property as nonatomic, you'll get the following:

// .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];
    }
}

Note the check ivar != newValue. If it was absent, ivar could be dealloc'ed after release, and the following retain would cause a memory access error.

When you declare your property with copy, the code will look almost the same, with retain replaced by copy.

For assign, it is even simpler:

- (void)setIvar:(id)newValue {
    ivar = newValue;
}

Now, when you declare your property as atomic (this one is the default), things get slightly more complicated. A snippet similar to the one below was posted by one of Apple's engineers on the development forums:

- (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];
        }
    }
}

Note the @synchronized block in both methods and additional retain-autorelease in the getter. Both those things ensure that you will either get the previous value (retained and autoreleased) or a new one in the case the value is changed by some thread while you are trying to read it.

鹿! 2024-10-31 23:57:33

这取决于您设置的属性,例如使用 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];
}

It depends on the attributes you set, for instance with a RETAIN attribute...

- (void)setAProp:(AnotherClass *)value {
   [aProp release];
   aProp = value;
   [aProp retain];
}

For ASSIGN attribute....

- (void)setAProp:(AnotherClass *)value {
   aProp = value;
}

For COPY attribute (used with NSString)...

- (void)setAProp:(AnotherClass *)value {
   aProp = [value copy];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文