В этой проверке нет необходимости, и она дает вам ложное чувство безопасности.
Вот проблема:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (!weakSelf) { return; }
// THE LINE OF INTEREST
[weakSelf doSomething];
});
В THE LINE OF INTEREST
какой-то другой поток может очистить последнюю сильную ссылку на self
, после чего weakSelf
устанавливается в nil. Таким образом, сообщение doSomething
отправляется на nil, что является «безопасным» (оно ничего не делает), но может оказаться не таким, как вы ожидали!
Хуже, если вы хотите предпринять другое действие, когда weakSelf
равно нулю, например.
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf) {
[weakSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
В этом случае между моментом, когда блок проверяет, что weakSelf
не является nil, и временем, когда он отправляет сообщение doSomething
, weakSelf
может стать nil, и ни doSomething
, ни doSomethingElse
фактически не будут выполняться.
Правильное решение такое:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
В этом случае копирование weakSelf
в strongSelf
(по умолчанию сильное) является атомарным. Если weakSelf
было нулем, strongSelf
будет нулем. Если weakSelf
не было nil, strongSelf
не будет nil и будет строгой ссылкой на объект, предотвращая его освобождение до сообщения doSomething
.
person
rob mayoff
schedule
17.06.2015
nil
в Obj-C, поэтому проверять его не нужно; например еслиweakself
равноnil
, то такой вызов метода не вызовет проблем в вашем блоке:[weakself doSomething];
. - person holex   schedule 17.06.2015