Objective-c属性未在ARC下发布

时间:2015-07-03 11:33:32

标签: ios objective-c xcode automatic-ref-counting

我想测试弧下的属性属性。我在 Class1.h (接口文件)下创建了两个NSString属性:

@interface Class1 : NSObject
@property (nonatomic, strong) NSString *str1;
@property (nonatomic, weak) NSString *str2;
@end

然后我在 Class1.m (实现文件)下创建了一个测试方法:

@implementation Class1

- (void)testMethod {
    NSString *strt1 = @"exampleString1";
    NSString *strt2 = @"exampleString2";

    self.str1 = strt1;
    self.str2 = strt2;

    strt1 = nil;
    strt2 = nil;

    dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, QOS_CLASS_BACKGROUND);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), aQueue, ^{
        [self testMethod2];
    });
}

- (void)testMethod2 {
    NSLog(self.str1);
    NSLog(self.str2);
}
@end

我在testMethod2方法中设置了一个断点,然后检查我的NSString属性。我假设str2设置为nil,但在运行代码后,结果为;

  

2015-07-03 14:14:04.412 ARCTEST [12303:6239959] exampleString1

     

2015-07-03 14:14:04.412 ARCTEST [12303:6239959] exampleString2

有人可以解释一下str2财产未被释放的原因吗?

3 个答案:

答案 0 :(得分:6)

Objective-c使用字符串文字池。这是所有字符串文字都是相同的(文本)指向同一个对象(因为字符串是不可变的)。这些字符串永远不会被释放。如果您将strt2的分配更改为。

,它将按预期工作
NSString *strt2 = [NSString stringWithFormat:@"%@", @"exampleString2"];

答案 1 :(得分:3)

因为它是一个字符串文字。它将在整个应用程序的整个生命周期中保留在内存中。尝试另一个课程,你会看到它会被释放。顺便说一句,在处理字符串时,最好使用copy而不是strongweak

答案 2 :(得分:0)

除了彼得和安德烈的正确答案之外,我想补充一点,你永远不能确定一个对象被解除分配,而弱引用被设置为nil

  • ARC不承诺尽快释放对象。
  • 可以在ARP中创建对象。在这种情况下,它在返回运行循环之前不会被释放。
  • 可以缓存对象以供重用。

期望解除分配只是错误的观点。你放弃了一个参考,没有别的。在参考文献中思考,而不是在生命中。

如果您希望引用为nil,则无效。不要依赖MM,因为它不是为此而制造的。