Итак, я мог бы не полностью схватить КОГДА я должен использовать weakSelf
в блоках. Я знаю, что это сделано для предотвращения циклов сохранения, а что нет, но я слышал, что есть некоторые исключения из этого правила.iOS - Должен ли я звонить «слабый» в этом блоке?
В следующем коде я проверяю, не удалось ли выполнить вызов API из-за истечения срока действия входа в систему, а затем я попытаюсь повторно аутентифицировать пользователя и повторить запрос API, который не удалось из-за этой проблемы, вызвав [self sendTask:request successCallback:success errorCallback:errorCallback];
в блок успеха повторного аутентификации:
/*!
* @brief sends a request as an NSHTTPURLResponse. This method is private.
* @param request The request to send.
* @param success A block to be called if the request is successful.
* @param error A block to be called if the request fails.
*/
-(void)sendTask:(NSURLRequest*)request successCallback:(void (^)(NSDictionary*))success errorCallback:(void (^)(NSString*))errorCallback
{
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
[self parseResponse:response data:data successCallback:success errorCallback:^(NSString *error) {
//if login session expired and getting "not authenticated" error (status 401)
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 401) {
NSLog(@"NOT AUTHENTICATED THO");
AuthenticationHelper* auth = [AuthenticationHelper sharedInstance];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
//attempt to re-authenticate the user
[AuthenticationHelper loginUser:[defaults stringForKey:@"username"] password:[defaults stringForKey:@"password"] successCallback:^(User* u)
{
auth.loggedInUser = u;
NSLog(@"RE-AUTHENTICATION BUG FIX SUCCEEDED");
//attempt to re-try the request that failed due to
[self sendTask:request successCallback:success errorCallback:errorCallback];
} errorCallback:^(NSString *error) {
NSLog(@"RE-AUTHENTICATION BUG FIX FAILED");
}];
}
else {
errorCallback(error);
}
}];
}];
[task resume];
}
Является ли эта плохая практика тем, что она может привести к циклу удержания? Если да, то почему? Должен ли я вместо этого использовать [weakSelf sendTask:request successCallback:success errorCallback:errorCallback];
, предполагая, что я делаю MyAPIInterface *__weak weakSelf = self;
заранее?
Я не понимаю, как само может содержать ссылку на блок. Можете ли вы привести пример этого, в котором это приведет к циклу сохранения? Простите меня, но я просто начал использовать блоки. – Rafi
Точно так же он может содержать ссылку на любой объект - переменную или свойство экземпляра. – Avi
@ Rafi - рассмотрите, что может произойти, если вместо локальной переменной 'task' вместо этого была переменная экземпляра: тогда у вас, возможно, есть' self' -> 'task' -> block ->' self' - который * потенциально * вызывает неприятный цикл (не все циклы плохие, особенно переходные). – CRD