5

Tôi đã nghe nói rằng tôi nên luôn luôn sử dụng weakSelf trong các khối để tránh giữ lại chu kỳ, nhưng những gì về khối công văn? Trong trường hợp này, phương pháp của tôi xử lý một phản ứng lỗi từ máy chủ của tôi trong đoạn mã sau:Tôi có nên sử dụng "weakSelf" trong khối công văn không?

//handling server errors (particularly "Token Refresh Failed" ones) 
-(void)handleServerErrorResponse:(NSString *)error { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     UIAlertController *alertController = [DialogHelper getAlertForSimpleAuthError:error]; 
     if ([error isEqualToString:@"Your login session has expired"]) { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 
      { 
       [MyModelDataCenter emptyDataCenter]; 
       [MyAPIInterface sharedInstance].authToken = nil; 
       NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
       [defaults removeObjectForKey:@"authToken"]; 
       [defaults removeObjectForKey:@"defaultUserObjectDictionary"]; 
       [defaults synchronize]; 
       [AuthenticationHelper sharedInstance].loggedInUser = nil; 
       [self.navigationController popToRootViewControllerAnimated:YES]; 
      }]]; 
     } 
     else { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; 
     } 
     [self presentViewController:alertController animated:YES completion:nil]; 
    }); 
} 

Tôi có nên sử dụng weakSelf trong khối này giống như tôi làm điều đó trong các khối khác?

Trả lời

8

Bạn cần sử dụng "điệu nhảy" yếu để tránh chu kỳ giữ lại chỉ khi có chu kỳ lưu giữ liên tục. Cho điều đó xảy ra, hai điều kiện cần phải được đáp ứng:

  • the Block thuộc sở hữu của một đối tượng được tham chiếu bên trong Khối
  • chủ sở hữu không nhả Khối trước deallocation riêng của mình

Nếu một trong những điều đó không đúng, không có chu kỳ lưu giữ liên tục và không có vấn đề gì.

Trong trường hợp này, không phải là đúng. Nói chung, các khối đặt lên hàng đợi sẽ không bị giữ lại chu kỳ, trừ khi bạn giữ Block xung quanh trong một ngà để tái sử dụng.

+0

Bạn có thể đưa ra ví dụ về thời điểm nó sẽ giữ lại không? – sbarow

+1

Đây là một ví dụ, mặc dù với một vài bước trung gian: http://stackoverflow.com/q/11822476/603977 –

+0

Cảm ơn bạn đã giải thích điều đó rất tốt! Và cảm ơn ví dụ! :) – Rafi

5

Thậm chí, tôi đồng ý với Josh và đã đồng ý ngay từ đầu, mà không có lý do cho weakifying self, nếu nó là không cần thiết (khối không giữ bởi một đối tượng tham chiếu), trong quá khứ đa làm yếu đi self làm mặc định. (Tôi nghĩ rằng những thay đổi lớn.)

Tuy nhiên, có thể là một lý do để weakify self thậm chí có không giữ lại chu kỳ:

hình ảnh mà bạn có một đối tượng dụ được lấp đầy bởi một khối dài chạy . Có thể là đối tượng thể hiện sẽ chết trong khi khối đang chạy, i. e. vì người dùng đã xóa nó. Trong trường hợp này, khối sẽ điền vào một đối tượng thể hiện không còn sử dụng nữa và biến mất khỏi mô hình của bạn, nhưng vẫn còn sống, bởi vì khối giữ nó. Làm suy yếu nó sẽ giải phóng nó và đặt self được chụp thành nil, những gì là dễ dàng để kiểm tra và thường đơn giản là không làm gì cả.

Nhưng tôi thực sự không nghĩ và chưa bao giờ nghĩ rằng kịch bản này biện minh cho một quy tắc của ngón tay cái "Làm suy yếu theo mặc định".

+0

Bạn có nói rằng nếu cuộc gọi API của tôi mất nhiều thời gian do kết nối internet chậm để nhận phản hồi từ máy chủ và nếu tôi bật 'UIViewController' có phương pháp xử lý lỗi này, ứng dụng của tôi sẽ bị lỗi? – Rafi

+1

Không, tôi không nói. Điều gì xảy ra, phụ thuộc vào mã cụ thể của bạn. Những gì tôi nói là: Nếu bạn có một tham chiếu mạnh mẽ đến đối tượng, nó sẽ không được deallocated, thậm chí không ai khác đang đề cập đến nó. Điều này làm gì với ứng dụng của bạn - tôi không thể biết. –

+0

Ok, cảm ơn thông tin. Tôi sẽ cẩn thận về những điều này :) – Rafi

Các vấn đề liên quan