1

Objective-C에서 self이 안전하지 않은 경우, 약한 객체에서 메소드를 호출하거나 속성에 액세스 할 정당한 이유가 없다고 일반적으로 말할 수 있습니까? 즉. 이 작업을 수행하지 :이 doStuff가 호출 될 때까지 범위에 남아 보장 자체에 대한 또 다른 강한 참조는하지만, 이것은 매우 가난한 이유 인 경우약한 객체에 대한 메소드를 호출해야 할 충분한 이유가 있습니까?

__weak typeof(self) weakSelf = self; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    [weakSelf doStuff]; 
}); 

물론, 기술적으로이 확인 될 수있다.

좋은 이유가 없다면 최소한 컴파일러 옵션 뒤에서 컴파일러가 이러한 호출을 거부하는 것이 좋습니다. document 당신이 참조에서

+0

귀하의 질문에 대한 대답으로, 일반적인 'weakSelf'패턴을 사용하는 데는 여러 가지 중요한 이유가 있습니다. 실용적인 이유 때문에, 귀하의 예와 똑같이하는 것이 거의 없습니다. 컴파일러가이 패턴을 거부하기를 원하지 않는다는 것이 확실합니다. 우리는 이것을 정확히하고 싶은 시나리오를 쉽게 만들 수 있습니다. 예를 들어, 이것이 뷰 컨트롤러의 네트워크 요청 완료 핸들러에 있고 모델 객체 업데이트를 마친 후 doStuff가 UI를 업데이트했다면 어떻게 될까요? 당신은 당신이 여기있는 것과 매우 흡사하게 행동 할 것입니다. – Rob

+0

그건 오타 였어. 나는 안전하지 않은 것을 의미했다. 네트워크 요청을 위해 [weakSelf doStuff]를 호출 할 필요는 없습니다. 당신은 항상 typeof (self) strongSelf = weakSelf를 할 수 있습니다; [strongSelf doStuff]; 분명히 약한 객체의 경우 doStuff 동안 객체가 근본적으로 강해지므로 strongSelf를 추가하면이 경우 중복 될 수 있습니다. –

+0

"강한"과 "약한"에서 "좋은"과 "가난한"의 이유를 설명하는 형용사가 변경되어 clang 메모리 관리 용어와 혼동을 일으키지 않도록했습니다.또한 할당 후 즉시 해제되기 때문에 진정한 __weak * 참조는 무의미하다고 생각하십시오. – danh

답변

2

: __weak 객체의 경우

는 현재 pointee은 유지하고 현재 전체 표현의 끝에서 해제됩니다. 할당 및 지적 자의 최종 릴리스에 대해 원자 적으로 실행해야합니다.

다시 말해 weakSelfdoStuff 방법의 지속 기간 동안 자동으로 유지되므로 안전합니다.

일반적으로 둘 이상의 메소드/속성을 호출하는 경우 약한 참조를 강력한 참조로 변환합니다.

+0

아 좋아. 내 질문은이 질문에 대한 답변에서 왔습니다 : http://stackoverflow.com/questions/32468758/objective-c-arc-does-a-method-retain-self. 나는 그 대답이 잘못되었다고 생각한다. –

-1

우리는 일반적으로 지금까지 아무 의미 약한 개체

아니, 메소드 또는 액세스 속성을 호출 할 강력한 이유가 없다고 말할 수 있습니다. 당신은 약한 객체에 대한 메소드를 항상 호출하고 있습니다! 예를 들어, 코코아에서 대부분의 delegate 개체는 weak입니다. 개체가 대리자를 유지하는 것이 잘못 될 수 있기 때문에 필요합니다. 그러나 대의원에 대한 메서드 호출은 대리자 패턴의 핵심입니다. 그렇지 않은 경우에 대한 대표자는 입니까?

예 : 여기 UIApplication delegate 선언 방법은 다음과 같습니다 비 ARC 약한 참조 (즉 어떤 assign 수단)이다

@property(nullable, nonatomic, assign) id<UIApplicationDelegate> delegate; 

합니다. 그러나 앱 위임자에게 보낼 수있는 메시지가 없다고 결코 말할 수는 없습니까?

+0

약한 객체에 대한 메소드 호출은 절대 사용하지 않는다는 것을 의미하지는 않습니다. 그것은 당신이 그들을 먼저 강하게 만들어야한다는 것을 의미합니다. 그러나 Darren이 지적했듯이, 컴파일러는 이미 이것을 수행합니다. –

+0

그러나 나는 그것을 믿지 않는다. 컴파일러는 약한'delegate'을 강하게 만들지 않습니다. 반대로, 더 이상 존재하지 않는 'delegate'에게 메시지를 보내는 것은 고전적인 "매달린 포인터"충돌 상황입니다. _ 안전하지 않습니다. 어떤 것도 그것을 강하게 만든다. 그랬다면 우리는 부서지지 않을 것입니다. 그러나 이것은 어리 석거나 나쁜 상황이 아닙니다. 안전을 유지하기위한 조치를 취해야합니다. 델리게이트가 객체에 대한 약한 참조를 가지고 객체보다 오래 남아 있는지 확인하는 것이 당신 일의 일부입니다. 그뿐입니다. 그러나 그것이 어떻게 든 약한 참조가 아니라는 것은 말도 안되는 것입니다. 물론 그것은 약하다. – matt

+0

"__weak 객체의 경우 현재 pointeeee가 유지 된 후 현재 전체 표현식의 끝에서 해제됩니다."라는 문서 부분을 믿지 마십시오. 그것이 유지되면, 마치 그것을 참조하는 강력한 변수가있는 것처럼 해제되지 않습니다. 델리게이트가 할당 해제되면 약한 참조는 무효가됩니다. nil 객체를 사용하면 배열에 추가하거나 직접 ivar에 액세스하는 것과 같이 특정 작업을 수행하지 않으면 충돌이 발생하지 않습니다. 그것은 완전히 별개의 토론이며 여기서의 질문은 아닙니다. –