Тази проверка е ненужна и ви дава фалшиво чувство за сигурност.
Ето го проблема:
__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
е зададено на нула. Така че съобщението doSomething
се изпраща до нула, което е „безопасно“ (не прави нищо), но може да не е това, което сте очаквали!
По-лошо е, ако искате да предприемете различно действие, когато weakSelf
е нула, напр.
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf) {
[weakSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
В този случай, между времето, когато блокът проверява, че weakSelf
не е нула, и времето, когато изпрати съобщението doSomething
, weakSelf
може да стане нула и нито 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
не е нула, strongSelf
няма да бъде нула и ще бъде силна препратка към обекта, предотвратявайки освобождаването му преди съобщението doSomething
.
person
rob mayoff
schedule
17.06.2015
nil
указател в Obj-C, така че не е необходимо да се проверява; като напр. акоweakself
еnil
, тогава такова извикване на метод няма да причини проблем във вашия блок:[weakself doSomething];
. - person holex   schedule 17.06.2015