2012-04-19 6 views
3

먼저이 예처럼, "unvalid"참조에 대한 문제를 (ARC를 사용) 설명 :내가 이해하지 약하고 강한 참조 책으로

NSDate* date1=[[NSDate alloc]init]; 
NSDate* date2=date1; 
[date1 release]; 
NSLog(@"%@",date2); // bad access 

그래서 나는/해제를 유지 메커니즘을 이해 :

date2=[date1 retain]; 

을하지만 강한/약한 참조에 대해 이야기 할 때, 그것은 나에게 모순처럼 들린다 :이 경우 명령이 될 것입니다. 기본적으로

", 참조가 강하고 요하는 경우 강한 참조에 객체를 할당하면 ARC는 그 객체를 계속 붙잡아두고 암시 적으로 유지하려고한다고 가정합니다. "

이전에 말한 것과 모순되지 않습니까?
date2는 기본적으로 강하므로 날짜 1을 암시 적으로 보유해야하며 잘못된 액세스 예외가 발생하지 않아야합니다.
물론 나는 뭔가를 잘못 이해하고있다.

답변

15

일반적으로 원하는 것이기 때문에 Strong이 기본값이지만 컴파일러는 ARC를 사용하여 개체의 수명을 분석하고 적절한 시간에 메모리를 해제해야합니다. 예를 들면 다음과 같습니다.

- (void)someMethod 
{ 
    NSDate* date = [[NSDate alloc] init]; // date is __strong by default 
    NSLog(@"The date: %@", date); // date still contains the object created above 

    // Sometime before this point, the object date pointed to is released by the compiler 
} 

약한 참조는 하나 이상의 다른 강력한 참조가있는 동안에 만 객체를 유지합니다. 마지막으로 강력한 참조가 끊어 지자 객체는 컴파일러에 의해 해제되고 런타임에 의해 약한 객체 참조 (변수)는 nil으로 변경됩니다. 위의 예와 같이 지역 변수에서 약한 변수를 거의 쓸모 없게 만듭니다. 예를 들어 :

- (void)someMethod 
{ 
    __weak NSDate* date = [[NSDate alloc] init]; // The date created is released before it's ever assigned to date 
               // because date is __weak and the newly created date has no 
               // other __strong references 
    NSLog(@"The date: %@", date); // This always prints (null) since date is __weak 
} 

가 로컬 범위에서 함께 작업 약한 강한 변수의 예를 보려면 (이 경우에만 엄격하게 제한 유용성을 것 정말 약한 변수 참조를 보여 만 여기에 표시됩니다) :

- (void)someMethod 
{ 
    NSDate* date = [[NSDate alloc] init]; // date stays around because it's __strong 
    __weak NSDate* weakDate = date; 

    // Here, the dates will be the same, the second pointer (the object) will be the same 
    // and will remain retained, and the first pointer (the object reference) will be different 
    NSLog(@"Date(%p/%p): %@", &date, date, date); 
    NSLog(@"Weak Date(%p/%p): %@", &weakDate, weakDate, weakDate); 

    // This breaks the strong link to the created object and the compiler will now 
    // free the memory. This will also make the runtime zero-out the weak variable 
    date = nil; 

    NSLog(@"Date: %@", date); // prints (null) as expected 
    NSLog(@"Weak Date: %@", weakDate); // also prints (null) since it was weak and there were no more strong references to the original object 
} 
+0

두 번째 예제 코드에서 "날짜가 __weak이므로 항상이 (null)을 출력합니다"라는 질문에서 날짜는 0이지만 메모리 누수가 있습니까? 또는 할당이 취소 되었습니까? –

+0

@RamyAlZuhouri 메모리 누수가 없습니다. 컴파일러는 새로 할당 된 날짜를 즉시 할당 취소하고 할당을 방해하지 않습니다 (이 경우). –

+0

NSLog (@ "약한 날짜 : % @", 날짜); NSLog (@ "Weak Date : % @", weakDate)가 아니어야합니다. – NMunro

3

중요한 실수는 수동 보유 해제 동작과 ARC가 동일한 것으로 간주하는 것입니다. 그렇지 않습니다. ARC에서 객체 할당은 객체 수명주기를 결정하는 표현식 자체 및 원자 표현식입니다.

예를 들어 retain을 제거하십시오. 당신은 이것으로 끝납니다 :

NSDate* date1=[[NSDate alloc]init]; 
NSDate* date2=date1; 
NSLog(@"%@",date2); 

ARC에서 완벽하게 의미합니다. 물건을 망쳐 버리는 수동 릴리스가 없습니다. 나는. 자동으로 작동합니다.

컴파일러가 흐름 제어 분석을 수행하기 때문에 필요한 추가 유지 또는 릴리스가 없습니다. 코드는 문자 그대로 될 것입니다 뭔가 같은 :

NSDate* date1; // date1 initialized to nil -- or not given that it is never read before... 
date1 = [[NSDate alloc]init]; // ... this assignment (of a +1 retain count obj) 
NSDate* date2=date1; // retain count unchanged 
NSLog(@"%@",date2); // retain count unchanged 
.... compiler emits equivalent to [date1 release] ... 

컴파일러가 releasedate1또는date2의 마지막 사용 후 때까지 매달려 포인터가있을 수 없다는 방출하지 것이기 때문에.

관련 문제