1

이 코드에 문제가 있습니까?성공 블록으로 비동기 네트워킹 호출을 할 때 iOS - View Controller 메모리 관리

[[MyNetworkManager shared] getSomeData:param success:^(NSDictionary *response) { 
    self.view.backgroundColor = [UIColor redColor]; 
} failure:^(NSString *errorString) { 

}]; 

특히 네트워크 작업이 완료되기 전에이 메서드를 호출하는보기 컨트롤러가 할당 해제되면 어떻게됩니까? 약하다. 자아가 강하다. 여기 요? 그 이유는 무엇?

는 네트워크 관리자는 네트워크 호출을하고 서버에서 유효한 데이터를 가져 오는 경우이 작업을 수행하여 호출 뷰 컨트롤러에 대한 응답을 반환 블록 자체이기 때문에

success(dictionary); 

그것은 나에게 좋은 것 같다 아무 곳에 나 유지되지 않지만 ... 틀릴 수 있습니다.

답변

5

여기서 self을 사용하면 네트워크 요청이 완료 될 때까지 View Controller가 할당 해제되지 않습니다. 여기에는 아무 것도 없으므로이 경우에는해야한다고 제안 할 것이므로 self의 사용은 부적절한 것 같습니다. 우리는 뷰 컨트롤러를 유지해야 할 필요가있는 시나리오를 만들 수 있습니다 (그러나 시나리오에서는 일정 수준의 코드 냄새가 나기도합니다).

여기서 weakSelf 패턴을 사용할 수 있으며보기 컨트롤러에 대한 강력한 참조가 유지되지 않습니다. 따라서 네트워크 요청이 완료되기 전에보기 컨트롤러가 해제되면 할당 해제되고 weakSelf 포인터는 nil이됩니다. 이것은 여기서 논리적 인 접근법으로 보인다.

그러나 weakSelf/strongSelf 패턴을 사용할 필요는 없습니다. 블록이 시작될 때 포인터가 nil이 아닌 경우 블록 실행 중 nil이되지 않도록해야 할 필요가있는 경우이를 사용합니다. 이 예제에는 적용 할 수 없습니다. 당신은 당신이 정말로 뷰 컨트롤러를 해제 한 후 실행 계속 질의를해야하는지 스스로에게 물어

typeof(self) __weak weakSelf = self; 

[[MyNetworkManager shared] getSomeData:param success:^(NSDictionary *response) { 
    weakSelf.view.backgroundColor = [UIColor redColor]; 
} failure:^(NSString *errorString) { 

}]; 

참고 :

는 그래서, 당신은 아마 같은 뭔가를 기대한다는 뜻입니다 . 그렇지 않은 경우이 요청을 취소 가능하게 만든 다음보기를 닫으면 취소 할 수 있습니다. 그러나 그것은 완전히 별개의 주제입니다.

+0

"여기에서 self를 사용하면 네트워크 요청이 완료 될 때까지 View Controller가 할당 해제되지 않습니다." 왜 그런가요? 뷰 컨트롤러를 유지하는 것은 무엇입니까? – soleil

+1

블록은 객체 참조가 '약함'(또는 훨씬 나쁘면 '__unsafe_unretained')이 아닌 한 블록 내에서 캡처 된 모든 객체에 대한 강력한 참조를 유지합니다. 따라서 'self'를 참조하면 블록이 해제 될 때까지 'self'에 대한 강력한 참조를 유지합니다. [Blocks Programming Topics] (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html)의 _Object 및 Block Variables_ 섹션을 참조하십시오. – Rob