2010-07-09 4 views
2

나는 이것에 대해 논의 된 바 있음을 알고 있지만, 일부 메모리 관리를 얻지 못했습니다. retain은 객체를 유지하고 copy는 객체의 사본을 별도로 제공한다는 것을 이해합니다.목표 C 메모리 관리의 어려움

property = newValue; 
// retain 
if (property != newValue) 
{ 
    [property release]; 
    property = [newValue retain]; 
} 

하지만 예 곳을 본 적이 : 그것은, & 속성을 인스턴스 변수 유지에 관해서 속성은 세터 출시 이전 값 &이 새를 유지한다는 뜻 내가하지 않는 무엇

입니다 그들은 고정 문자열을 retain 속성 ivars에 할당합니다.

self.stringProperty = @"something"; 
(some other code) 
self.stringProperty = @"somethingElse"; 

set string의 두 번째 호출은 허용되지 않는 정적 문자열에서 release를 호출해야합니다. 왜 프로그램이 중단되지 않습니까?

또한 객체가 retain 속성 &으로 선언 된 경우 init과 함께 무언가가 할당됩니다.

@property(retain)someArray; 

someArray = [[NSArray alloc] initWithArray:arbArray]; 

는 지금 someArray 평균 2의 유지 수를 가지고 있지만이

someArray = [NSArray arrayWithArray:arbArray]; 

로 생성 된 경우 2는 팩토리 메소드이기 때문에 계수는 1 유지 하는가?

+0

죄송합니다. 두 샘플 모두에서 self.someArray를 의미했습니다. –

답변

3

set string의 두 번째 호출은 허용되지 않는 정적 문자열에서 release를 호출해야합니다. 왜 프로그램이 중단되지 않습니까?

release을 상수 문자열로 전달할 수 있습니다. 아무 의미가 없으므로 해당 코드 줄이 유효합니다.

는 지금 someArray 평균 2의 유지 수를 가지고 있지만 그것으로 ... 테인 카운트를 만든 경우는 2가 팩토리 메소드 만 1 때문이다합니까? 우선

음,

someArray = [[NSArray alloc] initWithArray:arbArray]; 

@property에 의해 생성 된 방법을 사용하지 않는, 그냥 직접 바르에 액세스합니다. 속성 메서드를 사용하려면 self.someArray = ...;을 사용해야합니다.

그러나 예,

[[NSArray alloc] initWithArray:arbArray] 

1의 효과적인 유지 카운트 객체를 반환하고,

[NSArray arrayWithArray:arbArray] 

0의 효과적인 유지 카운트 개체를 반환, 그래서 당신이 한 경우@property으로 생성 된 "보유"설정기를 통과하면 ivar의 유효 보유 개수는 각각 2와 1이됩니다.

+0

감사합니다. 나는 모든 5 가지 C의 좋은 의사 소통을 기억할 수는 없지만 당신의 대답은 내가 기억할 수있는 3 가지를 충족시켰다 : 명확하고, 간결하며, 정확하다. –

0

더 많은 질문이 있지만 어쨌든 ...

정적 문자열은 여러 가지 특수한 경우이며, 그 중 하나는 효과가 없으면 마음 속으로 retainrelease 수 있습니다.

제쳐두고, NString 속성은 retain 의미보다 오히려 copy이되는 경우가 많습니다. 어쨌든 중요한 경우 그 질문을 제거합니다. 그러나 그렇지 않습니다. 직접 alloc (또는 copy 또는 기타 소유권-부여 호출)에서 retain 속성에 할당하는 두 번째 경우

나쁜 관행이며 적극적으로,시 등을 해당 나중에 release, 또는 autorelease을 추가하지 않으면 누출 :

self.someArray = [[[NSArray alloc] initWithArray:arbArray] autorelease]; 

그러나이 특별한 경우에 클래스 메소드를 사용하지 않을 이유는 없습니다.

+0

보유 수에 관한 두 번째 부분은 실제 질문이었습니다. 첫 번째 비트는 저를 괴롭히는 것이었지만 나중에 질문을 분리 할 것입니다. 응답 해 주셔서 감사합니다. –

0

set string의 두 번째 호출은 허용되지 않는 정적 문자열에서 release를 호출해야합니다. 왜 프로그램이 중단되지 않습니까?

정적 문자열이 아니며 상수 문자열입니다. 그러나이 질문과 관련이 없지만 실제로는 NSAutoreleasePool을 제외한 NSObject 에서 파생 된 Objective-C 객체를 보낼 수 있습니다. 상수 NSString의 retainCount (다소 장난 스럽지만 구현을 논의 할 것이므로 OK)를 살펴 보겠습니다.

NSLog(@"retain count = %u", [@"foo" retainCount]); 

사실 매우 큰 숫자로 설정되어있을 가능성이 큽니다 (실제로는 UINT_MAX). 이는 릴리스 및 유지할 호출을 무시하는 런타임에 대한 신호입니다.

그런데 개체를 놓는 것을 잊어 버리면 곧바로 프로그램이 중단되지 않습니다. 실제로 RAM이 많은 경우 OS가 교체되기 전까지는 알 수 없습니다.

는 그 someArray 지금 2의 유지 수를 가지고 의미 않지만 새로운 배열을 할당 속성을 사용하지 않았기 때문에 그것은,

없음으로 만들어진 경우, 당신은 바로 갔다 ivar :

self.someArray = [[NSArray alloc] initWithArray:arbArray]; 

은 누출이 될 수 있습니다.

self.someArray = [NSArray arrayWithArray:arbArray]; 

이면 괜찮습니다.