Objective-c 属性 未在 ARC 下发布
Objective-c property not released under the ARC
我想测试弧下的properties属性。我在 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
属性 没有发布?
因为它是一个字符串文字。它将在应用程序的整个生命周期内保留在内存中。尝试另一个 class,您会看到它会被释放。顺便说一句,在处理字符串时,你最好使用 copy
而不是 strong
或 weak
Objective-c 使用字符串文字池。那就是所有相同(文本)的字符串文字都指向同一个对象(因为字符串是不可变的所以有效)。这些字符串永远不会被释放。如果您将 strt2 的分配更改为,它将按预期工作。
NSString *strt2 = [NSString stringWithFormat:@"%@", @"exampleString2"];
除了 Peter 和 Andrey 的正确答案之外,我想补充一点,您永远无法确定某个对象是否已被释放并且弱引用已设置为 nil
。
- ARC 不承诺对象会尽早释放。
- 可以在 ARP 中创建一个对象。在这种情况下,它在返回 运行 循环之前不会被释放。
- 可以缓存对象以供重复使用。
期望释放是完全错误的观点。你放弃一个参考,没有别的。考虑参考文献,而不是生活时间。
如果您希望引用为 nil
,请将其置零。不要依赖MM,因为它不是为这个而生的。
我想测试弧下的properties属性。我在 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
属性 没有发布?
因为它是一个字符串文字。它将在应用程序的整个生命周期内保留在内存中。尝试另一个 class,您会看到它会被释放。顺便说一句,在处理字符串时,你最好使用 copy
而不是 strong
或 weak
Objective-c 使用字符串文字池。那就是所有相同(文本)的字符串文字都指向同一个对象(因为字符串是不可变的所以有效)。这些字符串永远不会被释放。如果您将 strt2 的分配更改为,它将按预期工作。
NSString *strt2 = [NSString stringWithFormat:@"%@", @"exampleString2"];
除了 Peter 和 Andrey 的正确答案之外,我想补充一点,您永远无法确定某个对象是否已被释放并且弱引用已设置为 nil
。
- ARC 不承诺对象会尽早释放。
- 可以在 ARP 中创建一个对象。在这种情况下,它在返回 运行 循环之前不会被释放。
- 可以缓存对象以供重复使用。
期望释放是完全错误的观点。你放弃一个参考,没有别的。考虑参考文献,而不是生活时间。
如果您希望引用为 nil
,请将其置零。不要依赖MM,因为它不是为这个而生的。