ivar 대신 속성을 릴리스했기 때문에 이것이 아니라면이 내용을 이해할 수 없습니다. 누군가 문제를 밝힐 수 있습니까?이 시점에서 소유하지 않은 참조 횟수의 감소가 올바르지 않습니다.
self.dataToBeLoaded = [[NSMutableData alloc] initWithLength:10000];
[self.dataToBeLoaded release];
경고는 Incorrect decrement of the reference count of an object that is not owned by the caller
입니다.
dataToBeLoaded
속성에는 해당 설정자와 관련된 retain 특성이 있습니다.
제 생각에는 alloc init이 보유 수를 증가시키고 속성 할당이 보유 수를 증가시킵니다. 나는 단 한 번만 그것을 지니고 있기 때문에, 그 일은 임무를 마친 직후에 풀어 놓는 이유입니다.
UPDATE - 일부 실험 결과는 : 그 아래에있는 내 의견에 언급 때문에
나는이 건물은 합성 세터로 수행 보유 내용에 모순 조언을받은, 내가 사용하는 작은 실험을 할 것이라고 생각 일부 로깅을 수정 위의 코드, 각 로그 문에서
NSLog(@"retain 1 = %d", [dataToBeLoaded_ retainCount]);
self.dataToBeLoaded = [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 2 = %d", [dataToBeLoaded_ retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [dataToBeLoaded_ retainCount]);
결과는 0 2이었고, 1
분명히, 그것은 개입하는 것은 불가능합니다 alloc 또는 0으로 1에서 2로 유지 카운트를 볼 초기화 코드. NSMutableData 클래스를 서브 클래 싱 할 수 있지만 시간이 부족했다.
retainCount 속성의 값에 의존 할 수 없다는 것을 많이 알고 있지만 일관성이있는 것처럼 보이고 예제에 표시된 것과 같은 코드의 짧은 범위에 대해 합당한 동작을 기대합니다. 그래서 저는 사전 충고가 정확하다고 믿을 것입니다 - 보유 재산은 세터 내에 보유를 포함하는 약속입니다. 그래서 여기에 alloc/init의 유지와 setter 호출의 유지가 있습니다. 나는이 코드를 실행하면 따라서 유지 수는 2
으로 설정됩니다
NSMutableData *theData;
NSLog(@"retain 1 = %d", [theData retainCount]);
theData= [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 1a = %d", [theData retainCount]);
self.dataToBeLoaded = theData;
NSLog(@"retain 2 = %d", [theData retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [theData retainCount]);
는 각 로그 문에서 수를 유지를 그래서
1. 내가 가진, 2, 1, 0 세터가 retain
을 제공하고 있음을 나타내는 증거. 이것은 실제로 일어나기 때문에 암시보다 더 많은 약속처럼 보입니다.
다른 설명이 열려 있습니다. 나는 이것에 대해 오만하지 않기를 바란다. 나는 다만 일어나고있는 무슨을에 관해서는 권리를 얻고 싶다. 나는 경고 (이 질문의 주제에)가 정말로 가짜이며 걱정할 것이 없다고 생각한다.
@property 문에서 속성으로 retain
이 아닌 assign
을 사용하면 한 번 더 실험을 수행 할 수 있습니다. 동일한 코드 : message sent to deallocated instance
:
NSMutableData *theData;
NSLog(@"retain 1 = %d", [theData retainCount]);
theData= [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 1a = %d", [theData retainCount]);
self.dataToBeLoaded = theData;
NSLog(@"retain 2 = %d", [theData retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [theData retainCount]);
(가) 각 로그에 카운트를 유지하여 0, 1, 1 (세터가 유지되지 않았다), 그 에러 메시지이다. 마지막 릴리스에서는 보유 수를 0으로 설정하여 할당 해제를 트리거했습니다.
UPDATE 2
마지막 업데이트 - 세터가 명시 적으로 포함하지 않는 합성 세터가 자신의 코드로 대체되면, 유지 속성은 더 이상 관찰되지 않는다. 분명히 (그리고 이것은 내가 여기에있는 다른 스레드에서 말한 것과 모순이됩니다.) 당신이 원한다면 세터에 자신의 소유권을 포함시켜야합니다. 여기서 테스트하지는 않았지만 이전 인스턴스를 먼저 릴리스해야합니다. 그렇지 않으면 누출됩니다.
이 지정 세터는 더 이상 @propety 선언의 등록 정보 속성이 없습니다 :
- (void) setDataToBeLoaded:(NSMutableData *)dataToBeLoaded {
dataToBeLoaded_ = dataToBeLoaded;
}
이 의미가 있습니다. 합성 된 setter를 재정의하고 선언 된 모든 속성을 무시합니다. 합성 된 setter를 사용하면 선언 된 속성이 합성 된 구현에서 관찰됩니다.
@property 속성은 합성 된 setter가 구현되는 방법에 대한 "약속"을 나타냅니다. 일단 사용자 정의 setter를 작성하면 스스로 해결할 수 있습니다.
저는 setter가 메소드 호출이라는 것을 알고 있습니다. 어쩌면 나는 속성이 보유 속성을 보유하고있는 경우 해당 설정자를 완전히 이해하지 못했을 수도 있습니다. 유지 된 속성에 대한 setter는 이전에 참조 된 인스턴스를 먼저 해제하고 (또는 말하자면 멀리 던집니다), 전달 된 인스턴스 참조를 할당 한 다음 유지합니다. 이제 전달 된 인스턴스는 이미 alloc/init에 의해 한 번 유지됩니다. - 그런데 참조 된 인스턴스가 0이되면 버려진 참조 된 인스턴스는이 프로세스에서 유출되지 않습니다. 당신의 설명에 뭔가 빠졌습니까? – Jim
API 약속보다는 특정 구현에 대해 너무 많이 가정합니다. 당신은'setDataToBeLoaded :'가 ivar을 할당하고 그것을 유지한다고 가정하고 있습니다. 이것은 API가 약속하지 않은 것입니다. "보유"속성은 API의 약속이 아닙니다. 그것은 힌트이며, @synthesize에 의해 사용됩니다 (그러나 @synthesize는 API와 관련이 없습니다). 희망적으로 더 명확하게되기를 바란다 : 당신이 소유하지 않은 것을 절대로 공개하지 마십시오. 'dataToBeLoaded'를 호출해도 반환 값의 소유권을 갖지 않습니다. 메소드에 이름에 새/copy/alloc이 없습니다. 당신은 그것을 소유하지 않습니다. –
누설이 없다고 말씀하셨습니다. 당신은 실제로 있습니다. 당신은 누설되고 당신은 과도하게 풀어 놓았고, 둘은 균형을 이루기 때문에 Instruments에서 누수가 보이지 않습니다.그러나 정적 분석기는 두 가지 모두에 유의해야합니다. –