2012-01-01 1 views
0

dealloc에서 포인터를 nil로 설정하지 않으면 두 번째 개체가 dealloc 될 때 두 번째 개체에서 생성 된 개체가 dealloc되지 않습니다.ARC에서 개체가 삭제되지 않습니다.

개체가 dealloc 될 때 ARC는 기본적으로 모든 포인터를 nil로 설정해야한다고 생각하여 소유 한 개체를 해제합니다. 내가 뭔가 잘못하고

@interface Obj1 : NSObject 
{ 
    Obj2 *obj2; 
} 

@interface Obj2 : NSObject 
{ 
} 

@implementation Obj1 

-(void)dealloc 
{ 
    obj2 = nil; // <--- This is needed to get obj2 to be dealloc'd. 
    NSLog(@"Obj1 dealloc"); 
} 

-(id)init 
{ 
    if ((self = [super init]) == nil) 
     return nil; 

    obj2 = [[Obj2 alloc] init]; 

    return self; 
} 

@end 

@implementation Obj2 

-(void)dealloc 
{ 
    NSLog(@"Obj2 dealloc"); 
} 

-(id)init 
{ 
    if ((self = [super init]) == nil) 
     return nil; 

    return self; 
} 

@end 

암 : 여기

은 (단지 코어) 내 코드? 내가 읽은 모든 것은 이것이 작동해야한다고 말한다. 아무도 obj2를 보유하고 있지 않으므로 obj2를 설정하지 않으면 obj2가 해제됩니다. dealloc 함수를 사용하거나 사용하지 않고 코드를 시험해 보았습니다. 뭔가를 망칠 경우를 대비해서 동일한 결과를 얻었습니다.

파일이 obj-C++로 컴파일되고 있지만 C++ 및 개체로는 아무 것도하지 않습니다.

감사합니다.

+0

OK :

는 다음 입력 파일이 저장된 디렉터리로 변경, 당신은 arc_tst.m 그것을라는 이름의 한 가정을 컴파일하려면 , 나는 그 문제를 발견했다. 좀비 오브젝트 사용 설정을했습니다. 그것이 nil로 설정되지 않은 경우 객체가 삭제되지 않도록하는 것이 놀랍습니다. 나는 좀비 오브젝트가 삭제 된 후에 그 오브젝트 대신에 놓인다고 생각했습니다. dealloc을 호출하지 않으면 더 큰 문제가 발생할 수 있습니다. –

답변

1

이것은 예상대로 작동해야합니다. 예를 들어 코드에서 난독 화되었거나 잘리지 않은 코드에서 실수로 무언가를하고있는 것입니다. 시연을 위해 아래 코드를 파일 (예 : arc_tst.m)에 저장하고 컴파일 한 다음 터미널에서 실행할 수 있습니다. 예상되는 모든 로그 문을 출력 한 다음 두 객체의 할당을 해제하여 끝납니다. 이 객체는 여기에 게시 된 예제 코드에서 모델링 된 것과 똑같습니다 (실제 코드의 다른 부분에서 문제가 발생할 가능성이 있음을 보여줍니다).

$ clang -fobjc-arc -o arc_tst arc_tst.m -framework foundation 
$ ./arc_tst 

arc_tst.m

// build with: clang -fobjc-arc -o arc_tst arc_tst.m -framework foundation 

#import <Foundation/Foundation.h> 

@class Obj1, Obj2; 

@interface Obj1 : NSObject 
{ 
    Obj2* _obj2; 
} 

@end 

@interface Obj2 : NSObject 
{ 
} 

@end 

@implementation Obj1 

- (id)init 
{ 
    if((self = [super init])) 
    { 
    _obj2 = [[Obj2 alloc] init]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    NSLog(@"Obj1 Dealloc"); 
} 

@end 

@implementation Obj2 

- (id)init 
{ 
    if((self = [super init])) 
    { 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    NSLog(@"Obj2 Dealloc"); 
} 

@end 

int main (int argc, char const *argv[]) 
{ 
@autoreleasepool { 
    Obj1* obj = [[Obj1 alloc] init]; 
    NSLog(@"after alloc, have obj1: %@", obj); 
    sleep(2); 
    NSLog(@"after sleep, have obj1: %@", obj); 
    obj = nil; // force ARC to trash obj 
    NSLog(@"after nil on obj1, about to exit"); 
} 
return 0; 
} 
+0

코드 예제는 설명대로 작동합니다. 나는 내 코드에서 내가 뭘하는지 알 수 없다. 내 Obj1이 할당 해제되고 있지만, Obj2를 nil로 설정하지 않으면 Obj2가 아닙니다. 내 코드를 obj-C++로 컴파일하고 있는데 어떤 차이가 있는지 모르겠습니다. –

+0

@RogerGilbrat 흠 ... 그게 효과가 있을지도 몰라. 질문에 태그를 추가했지만 질문을 업데이트하여이 코드를 사용하는 방법과 C++ 코드와 상호 작용하는 방법을보다 정확하게 말할 수 있습니다. –

+0

C++ 코드와 대화식이 아닙니다. 내가 C++을 사용하는 유일한 방법은 param 타입을 기반으로 순수한 c 함수를 오버로드 할 수 있다는 것입니다. 그게 전부 야. 삭제되지 않는 객체는 C++로 아무 일도하지 않습니다. 모든 것은 순수한 obj-c입니다. –