2

Я некоторое время боролся с этой проблемой, так как не думаю, что полностью понимаю циклы сохранения. Я совершенно новичок в этом, и я пытаюсь узнать больше об этом.EXC_BAD_ACCESS при использовании weakSelf в блоке/блоках

Я получаю сообщение EXC_BAD_ACCESS со следующим кодом.

Я начал использовать weakSelf, потому что получаю 2 предупреждения об удержании цикла, если я просто использую self.successBLock() ;. Точное предупреждение:

Capturing 'self' strongly in this block is likely to lead to a retain cycle 

Возможно, я не должен даже беспокоиться об использовании слабых, но я не уверен в этом.

Это та часть, где я использовать weakSelf в блоке:

__weak Request *weakSelf = self; 

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
    weakSelf.successBlock(operation.response, responseObject); 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    weakSelf.failureBlock(operation.response, error); 
}]; 

Это, как я назначить свойство блока:

typedef void (^successBlock)(NSHTTPURLResponse *response, id responseObject); 
typedef void (^failureBlock)(NSHTTPURLResponse *response, NSError *error); 

@property (nonatomic, copy) successBlock successBlock; 
@property (nonatomic, copy) failureBlock failureBlock; 
+0

В какой именно строке вы принимаете ошибку. –

+0

На этих двух строках: weakSelf.successBlock (операция. Ответ, responseObject); слабыйSelf.failureBlock (работа. Ответ, ошибка); – Nipje

ответ

7

__weak задания устанавливается в nil если объекте он указывает на освобождение. Итак, если ваш объект Request уже освобожден, если блок завершения составляет , то weakSelf - nil. В этом случае weakSelf.successBlock оценивает указатель NULL и вызывает сбои.

Следующая модель позволяет избежать этой проблемы:

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
    Request *strongSelf = weakSelf; 
    if (strongSelf) { 
     strongSelf.successBlock(operation.response, responseObject); 
    } 
} ... 

strongSelf будет nil если объект Request уже высвобождены. В противном случае сильная ссылка гарантирует, что объект не будет освобожден во время выполнения блока.

С другой стороны, если вы хотите, чтобы объект Request существовал до тех пор, пока не будет вызван блок завершения , вам не следует использовать слабую ссылку.

+0

Когда я пытаюсь использовать шаблон, он никогда не вводит оператор if. Он вводит блок отказа или успеха. Вы знаете, что вызывает это? Также, когда я меняю __weak на __strong, код, похоже, работает. Это было что-то, что я пробовал, и я не уверен, что это правильное решение. – Nipje

+0

@ user2362596: Использование 'self' в блоке может быть правильным решением (вот что я имел в виду с последним предложением в моем ответе). Во время выполнения операции вы будете иметь «временной цикл сохранения». Как только операция завершается и блок завершения вызывается, захваченное «я» исчезает, и цикл сохранения прерывается. –

+0

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

0

Когда weakSelf настроено на ноль, weakSelf.successBlock - штраф, но weakSelf.successBlock(operation.response, responseObject) потерпит крах.

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