我以为我已经非常了解弱引用和块,但是在尝试下面的代码片段时,有一些我不明白的东西。
方法测试1:没有保留对象一切都很好
方法test2:我不明白为什么对象似乎一直保留到方法test3结束!即使在方法test2object = nil
的末尾显式设置也不会改变任何东西。
方法test3:不保留对象。为什么方法test2的行为不是这样?
作为一个附带问题,我实际上想知道弱变量是否是线程安全的?即,如果我在尝试从不同线程访问弱变量时永远不会得到任何 BAD_ACCESS 异常。
@interface Object : NSObject
@property (nonatomic) NSInteger index;
@end
@implementation Object
- (id)initWithIndex:(NSInteger) index {
if (self = [super init]) {
_index = index;
}
return self;
}
- (void)dealloc {
NSLog(@"Deallocating object %d", _index);
}
@end
测试方法
- (void) test1 {
NSLog(@"test1");
Object* object = [[Object alloc] initWithIndex:1];
NSLog(@"Object: %@", object);
__weak Object* weakObject = object;
dispatch_async(dispatch_queue_create(NULL, NULL), ^{
//NSLog(@"Weak object: %@", weakObject);
[NSThread sleepForTimeInterval:2];
NSLog(@"Exiting dispatch");
});
[NSThread sleepForTimeInterval:1];
NSLog(@"Exiting method");
}
- (void) test2 {
NSLog(@"test2");
Object* object = [[Object alloc] initWithIndex:2];
NSLog(@"Object: %@", object);
__weak Object* weakObject = object;
dispatch_async(dispatch_queue_create(NULL, NULL), ^{
NSLog(@"Weak object: %@", weakObject);
[NSThread sleepForTimeInterval:2];
NSLog(@"Exiting dispatch");
});
[NSThread sleepForTimeInterval:1];
NSLog(@"Exiting method");
}
- (void) test3 {
NSLog(@"test3");
Object* object = [[Object alloc] initWithIndex:3];
NSLog(@"Object: %@", object);
NSValue *weakObject = [NSValue valueWithNonretainedObject:object];
dispatch_async(dispatch_queue_create(NULL, NULL), ^{
NSLog(@"Weak object: %@", [weakObject nonretainedObjectValue]);
[NSThread sleepForTimeInterval:2];
NSLog(@"Exiting dispatch");
});
[NSThread sleepForTimeInterval:1];
NSLog(@"Exiting method");
}
- (void) test {
[self test1];
[NSThread sleepForTimeInterval:3];
[self test2];
[NSThread sleepForTimeInterval:3];
[self test3];
}
上面的输出是:
2013-05-11 19:09:56.753 test[1628:c07] test1
2013-05-11 19:09:56.754 test[1628:c07] Object: <Object: 0x7565940>
2013-05-11 19:09:57.755 test[1628:c07] Exiting method
2013-05-11 19:09:57.756 test[1628:c07] Deallocating object 1
2013-05-11 19:09:58.759 test[1628:1503] Exiting dispatch
2013-05-11 19:10:00.758 test[1628:c07] test2
2013-05-11 19:10:00.758 test[1628:c07] Object: <Object: 0x71c8260>
2013-05-11 19:10:00.759 test[1628:1503] Weak object: <Object: 0x71c8260>
2013-05-11 19:10:01.760 test[1628:c07] Exiting method
2013-05-11 19:10:02.760 test[1628:1503] Exiting dispatch
2013-05-11 19:10:04.761 test[1628:c07] test3
2013-05-11 19:10:04.762 test[1628:c07] Object: <Object: 0x71825f0>
2013-05-11 19:10:04.763 test[1628:1503] Weak object: <Object: 0x71825f0>
2013-05-11 19:10:05.764 test[1628:c07] Exiting method
2013-05-11 19:10:05.764 test[1628:c07] Deallocating object 3
2013-05-11 19:10:05.767 test[1628:c07] Deallocating object 2
2013-05-11 19:10:06.764 test[1628:1503] Exiting dispatch