2014-06-26 3 views
2

мне нужно выполнить ту же кучу кода в двух блоках (я использую ARC):Используя метод с собой внутри блоков

__weak typeof(self) weakSelf = self; 
[_dataProvider doA:^(NSError *error) { 
    [weakSelf handleError:error]; 
}]; 

И в другом месте я называю:

__weak typeof(self) weakSelf = self; 
[_dataProvider doB:^(NSError *error) { 
    [weakSelf handleError:error]; 
}]; 

Затем у меня есть мой обработчик:

- (void)handleError:(NSError *)error { 
    [self.refreshControl endRefreshing]; 
    [self.tableView reloadData]; 
} 

Можно ли использовать его таким образом? Пожалуйста, обратите внимание, что метод handleError: использует self внутри. Если нет, то какой здесь подход? BTW: self является viewController и может быть освобожден (doB: и doA: блоки основаны на сети, поэтому могут быть медленными).

+0

Как вы относитесь к его безопасному использованию? это не повредит ваше устройство ... так что да, это безопасно в этом плане. – holex

+0

Это не «полностью» безопасно, см. Мой ответ. – samir

ответ

2

Небезопасно это делать, даже если многие люди делают это так.

Вы должны использовать шаблон «weakSelf» с блоками, когда это оправдано. В вашем примере шаблон «weakSelf» не является оправданным, потому что self не имеет strong ссылки на ваш block. Вы можете использовать так:

[_dataProvider doA:^(NSError *error) { 
    // here you can use self, because you don't have any strong reference to your block 

    [weakSelf handleError:error]; 
}]; 

Использование «weakSelf» шаблон, если у вас есть strong ссылку на ваш block (со свойством или переменной экземпляра, например), и ваши захватывают self внутри block, например:

@property(strong) void(^)(void) completionBlock; 
.... 

__weak typeof(self) weakSelf = self; 

    self.completionBlock = ^{ 
     // Don't use "self" here, it will be captured by the block and a retain cycle will be created 
     // But if we use "weakSelf" here many times, it risques that it will be nil at the end of the block 
     // You should create an othere strong reference to the "weakSelf" 
     __strong typeof(self) strongSelf = weakSelf; 
     // here you use strongSelf (and not "weakSelf" and especially not "self") 
    }; 
+0

Я слышал что-то подобное. Однако xCode не соглашается с этим, насколько я понимаю, «[_someInstance doC:^(ошибка NSError *) {self.index + = 5; }]; '(где' @property (неатомный, назначать) индекс NSInteger; '). XCode утверждает, что 'Capturing 'self' сильно в этом блоке, вероятно, приведет к сохранению цикла'. У меня нет ни собственности, ни ivar для этого блока, почему я получаю предупреждение? – Vive

+0

я отключу предупреждение, выполнив: #pragma лязг диагностического толчка #pragma лязг диагностических игнорируемый «-Warc-сохраняющих циклы» .... Ваш блок здесь #pragma лязг диагностики поп – samir

+0

Так вы утверждаете, что это общее предупреждение, и я не должен заботиться об этом в этом конкретном случае? Обычно я нахожу предупреждения полезными, и я боюсь, что у этого предупреждения есть некоторая «правда». Однако, если вы уверены, что в этом случае все в порядке, я понимаю, как это работает. – Vive

 Смежные вопросы

  • Нет связанных вопросов^_^