0

使用属性,我想要一个公开可见的 getter 和一个私有可见的 setter,用于具有弱引用的对象。我认为我有一些可以使用类扩展的东西。好吧,直到我在将对象设置为 nil 之前和之后都调用了 getter。如果我只在对象设置为 nil 之前或之后调用,getter 就会起作用。这是我所拥有的:


酒吧.h

#import <Foundation/Foundation.h>

@interface Bar : NSObject
@property (nonatomic, readonly, weak) NSObject *object;  // note only readonly
- (id) initWithObject:(NSObject *)object;
@end

巴.m

#import "Bar.h"

@interface Bar ()  // class extension
@property (nonatomic, readwrite, weak) NSObject *object;  // note readwrite
@end

@implementation Bar

- (id) initWithObject:(NSObject *)object
{
    self = [super init];
    if (self)
    {
        self.object = object;
    }
    return self;
}

@end

主程序

#import "Bar.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {

        // Call getter once, before setting the object to nil.
        // This appears to work.
        NSObject *object1 = [[NSObject alloc] init];
        Bar *bar1 = [[Bar alloc] initWithObject:object1];
        NSLog(@"before      - bar1.object[%p] object1[%p]",bar1.object, object1);

        // Call getter once, after setting the object to nil.
        // This appears to work.
        NSObject *object2 = [[NSObject alloc] init];
        Bar *bar2 = [[Bar alloc] initWithObject:object2];
        object2 = nil;
        NSLog(@"after       - bar2.object[%p] object2[%p]",bar2.object, object2);

        // Call getter twice, before and after setting the object to nil.
        // This appears to work to work for the first call to the getter.
        NSObject *object3 = [[NSObject alloc] init];
        Bar *bar3 = [[Bar alloc] initWithObject:object3];
        NSLog(@"both before - bar3.object[%p] object3[%p]",bar3.object, object3);
        object3 = nil;
        NSLog(@"both after  - bar3.object[%p] object3[%p]",bar3.object, object3);

        return 0;
    }
}

结果

before      - bar1.object[0x9623030] object1[0x9623030]
after       - bar2.object[0x0] object2[0x0]
both before - bar3.object[0x7523d90] object3[0x7523d90]
both after  - bar3.object[0x7523d90] object3[0x0]

我预计那both after是:both after - bar3.object[0x0] object3[0x0].

nil在将对象设置为之前调用 getternil并在之后再次调用它时,似乎没有设置弱引用。

4

1 回答 1

1

当您之前调用 getter 时,弱属性被加载并转换为强引用,然后被自动释放。当您再次调用它时,object3正如nil预期的那样,但它引用的原始对象仍然存在,位于自动释放池中。因此bar3.object仍有一个有效的对象返回给你。

请尝试以下操作:

NSObject *object3 = [[NSObject alloc] init];
Bar *bar3 = [[Bar alloc] initWithObject:object3];
@autoreleasepool {
    NSLog(@"both before - bar3.object[%p] object3[%p]",bar3.object, object3);
}
object3 = nil;
NSLog(@"both after  - bar3.object[%p] object3[%p]",bar3.object, object3);
于 2013-04-04T23:25:16.277 回答