Я думал, что я понял довольно слабые ссылки и блоки, однако при попытке найти ниже фрагменты кода есть несколько вещей, которые я не понимаю.Блоки ARC, слабый и удерживаемый счет
Метод test1: все в порядке, если объект не сохраняется
Метод test2: Я не понимаю, почему объект, кажется, не получить сохраняется до конца метода test3! Даже явно установка object = nil
в конце метода test2 ничего не меняет.
Способ 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
Хорошо, что заявление NSLog делает разницу между тестом 1 и тестом 2! (Потому что он упоминает «слабый объект», внося его в блок.) – matt
Получаю, однако, слабый объект является локальной переменной __weak, поэтому не следует ли увеличивать счетчик удержания? Или он может быть скопирован как сильная переменная, когда он доступен внутри блока? – quentinadam
См. Http://stackoverflow.com/a/11603363/341994 для одной части вашего q. – matt