2010-07-21 3 views
1

Objective C 속성의 참조 계산을 이해할 수 있도록 도와 주시겠습니까?Objective-C 속성 참조 수

가정하자 나는 나의 이해는 다음과 같은 논리에 해당 예 : "ta.tb = NEWVALUE"로, "TB"새로운 값의 할당이다 클래스

@interface TA : NSObject 
{ 
    TB* tb; 
} 
- (id) init; 
- (void) dealloc; 
@property (nonatomic,retain) TB* tb; 
@end 

@implementation 
@synthesize tb; 
- (id) init {...} 
- (void) dealloc {...} 
@end 

있습니다

if (newValue != oldValue) 
{ 
    [newValue retain]; 
    [oldValue release]; 
    tb_storage_cell = newValue; 
} 

그러나 초기화 방법으로 어떻게 작동합니까?

[TA 할당] 인스턴스 메모리를 0으로 사전 초기화 하시겠습니까?

tb = nil 안에 실행해야합니까?

ALLOC 만약 그렇다면 그것은 TB 이미 닐 때문에 = 닐가 INIT 내부 불필요 TB 설정 표시 제로로 메모리에 미리 초기화. 그게 맞습니까?

할당 메모리가 0이 아니고 가비지가 포함 된 경우 초기화 할당 내에서 이전 값을 해제하려는 시도가 중단되어 작동하지 않을 수 있습니다. 그렇다면 alloc이 항상 zero-out 메모리 블록을 반환하도록 보장된다는 것을 의미합니까?

다음으로는 dealloc입니다.

[tb release]; 
tb = nil; 
[super dealloc]; 

것을 잘가요 :

세웠 순서는 의 dealloc 내부는?

그렇다면 어떻게 다시 작동합니까? 먼저 릴리스은 "tb"를 릴리스해야합니다. 그런 다음 과제 "TB = 전무는"다시 결핵의 oldValue입니다을 출시 할 예정이다, 그래서 ... 더블 자료와 충돌에

을 금액해야 또는 내가 "[TB 자료]"건너 뛸 생각하고있는 의 dealloc 내부 및 간단히 수행

tb = nil; 
[super dealloc]; 

?

답변

3

Objective-C 사양은 모든 개체 인스턴스가 할당 될 때 멤버가 0으로되어 있음을 명시 적으로 나타냅니다.

속성의 get 및 set 메서드는 instance.property 구문을 사용할 때만 호출됩니다. "tb = nil"라인은 단순히 인스턴스 변수의 값을 nil로 설정하고 속성을 호출하지 않습니다.

속성 설정 도구를 호출하려면 self.tb = nil을 수행해야합니다. 일반적으로 dealloc 메소드에서 값을 공개 할 때는 항상 특성 구문을 사용해야합니다.

self.tb = nil; 

이렇게하면 속성이 제대로 해제되고 제외됩니다.

+1

네, 항상'tb = nil'은 인스턴스 변수를 직접 설정하고 속성과 아무 관련이 없습니다. 반면에'self.tb = nil'은'[self setTb : nil]'과 동일하고 당신은 말했다 ('if (newValue! = oldValue)'등). – andyvn22

+2

접근자는 단순히 인스턴스 변수에 값을 지정하거나 할당하는 것 이외의 부작용을 가질 수 있기 때문에 일반적으로 initializers 및 dealloc 메서드에서 속성 액세스를 피하는 것이 좋습니다 (KVO 알림). – Chuck

0

로 당신은 당신의 방법을 쓸 수있다 :

-(id) init{ 
if(self=[super init]){ 
tb = [[TB alloc] initWithSomething]; 
} 
return self; 
} 

- (void) dealloc{ 
[tb release]; 
[super dealloc]; 
} 
- (void) someMethod{ 
NSLog(@"This is ok since tb is always initialized. %@", [tb description]); 
NSLog(@"This is also ok. %@", [tb description]); 
} 

이것은 typic 초기화, 또는 당신은 결핵이 beggining에서 initializaed 할 필요가 없습니다이라고 생각하면, 당신은 그것을 게으른 만들 수 :

-(tb) tb{ 
if (!tb) 
    tb = [[TB alloc] initWithSomething]; 
return tb 
} 

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

- (void) dealloc{ 
[tb release]; 
[super dealloc]; 
} 
- (void) someMethod{ 
NSLog(@"This might be not ok, tb is not necessarily initialized:%@ ", [tb description]); 
NSLog(@"This is ok since tb is always initialized by the getter. %@", [self.tb description]); 
} 

이렇게하면 코드의 다른 부분에서 초기화하지 않는 한 속성이 초기화되도록 tb를 호출해야합니다.