9

ARC에서 이상한 objc_setAssociatedObject 동작이 발생했습니다. 다음 코드를 고려하십시오ARC에서 누출되는 Objective-C 관련 개체

static char ASSOC_KEY; 

@interface DeallocTester : NSObject 
@end 

@implementation DeallocTester 
- (void) dealloc 
{ 
    NSLog(@"DeallocTester deallocated"); 
    //objc_setAssociatedObject(self, &ASSOC_KEY, nil, OBJC_ASSOCIATION_RETAIN); 
} 
@end 

@implementation AppDelegate 
- (void) applicationDidFinishLaunching:(UIApplication *)application 
{ 
    NSObject *test = [[DeallocTester alloc] init]; 
    objc_setAssociatedObject(test, &ASSOC_KEY, [[DeallocTester alloc] init], 
          OBJC_ASSOCIATION_RETAIN); 
} 

내가 DeallocTester의 인스턴스를 만드는거야을, 그때는 둘 다의 범위를 벗어나 이동, 그것을 위해 관련 개체로 다른 DeallocTester을 설정합니다.

첫 번째 개체의 -dealloc이 호출 될 예정이며, 관련된 개체도 할당 해제 될 것으로 예상되지만, "DeallocTester deallocated" 메시지는 한 번만 인쇄됩니다. objc_setAssociatedObject 라인에서 -dealloc의 주석 처리를 제거하면 두 번째 객체의 할당이 해제됩니다.

Objective-C 참조는 연결된 개체가 개체가 제거 될 때 자동으로 할당이 해제된다는 것을 나타냅니다. 컴파일러/ARC/어떤 문제인지 또는 내가 놓친 것이 있습니까? 당신은 아주 새로운 프로젝트에서 실행하는 경우

업데이트

이 샘플 코드는 실제로 노력하고 있습니다. 하지만 ARC가 지원되지 않는 프로젝트는 두 곳 있습니다. 몇 가지 조사를하고 더 나은 샘플을 제공 할 것입니다. ARC에서 광고로 나는 rdar://10636309, Associated objects leaking if NSZombie objects enabled in ARC-enabled project

+0

아이폰 OS에서 수정 될 것으로 보인다 ? 클래스의 카테고리에 iVars 및 속성을 대신 작성할 수 있습니다. – Abizern

+0

@Abizern 'NSObject'에 ivars를 추가 할 예정입니다. AFAIR ivars는 클래스 확장 카테고리에만 추가 할 수 있고 임의의 클래스에는 추가 할 수 없습니다. – iHunter

+0

@Abizern 정말요? 카테고리에서 아이어를 어떻게 만듭니 까? – jlehr

답변

9

문제점의 원인을 찾았습니다.이 버그가 나타나는 두 프로젝트에서 모두 NSZombie 개체가 사용 설정되었습니다.

내가 아는 한 좀비 개체를 사용하면 일반 인스턴스는 할당 해제시 NSZombie으로 바뀌지 만 모든 연결된 개체는 살아 있습니다! 그 행동을 조심하십시오!

나는 rdar://10636309

업데이트를 만들었습니다 :이 세드릭 Luthi하여 workaround, 그리고이 문제는 연관된 객체를 사용하면 LLVM3를 사용하는 + 이유를 사용하는 경우 6.

+0

기본적으로 NSZombie를 사용하지 않는 또 다른 이유가 있습니다. – jlehr

+0

@jlehr 그리고 다른 이유는 무엇입니까? 난 항상 내 프로젝트에서 그들을 가능하게하고 지금까지 어떤 단점도 보지 못했다. 내가 놓친 게 있니? 고맙습니다. – iHunter

+1

좀비를 사용하도록 설정하면 다양한 문제를 숨길 수 있으며 물론 앱이 엄청난 양의 메모리를 유출하게됩니다. – jlehr

1

코드를 작성했습니다 2

업데이트는 정확히 작동을 기록했다. 좀 더 분명하게하기 위해 dealloc 구현을 다시 작성했습니다.

2012-01-03 06:49:39.754 ARC Stuff[47819:10103] deallocating <DeallocTester: 0x6878800> 
2012-01-03 06:49:39.756 ARC Stuff[47819:10103] deallocating <DeallocTester: 0x688b630> 

당신이 사용할 수는 ARC 컴파일하고 확실 : 여기

- (void)dealloc 
{ 
    NSLog(@"deallocating %@", self); 
} 

는 결과 로그입니까?

+0

와우! 어떤 OS/Xcode 버전을 사용하고 있습니까? – iHunter

+0

Xcode 4.2에서 10.7.2를 실행했습니다. – jlehr

+0

나도. 나는 이제 다시 새로운 프로젝트를 점검 할 것이다. – iHunter