@synthesized 유지 속성에 대한 릴리스는 어떻게 처리됩니까?
Objective-C의 합성 속성에 대해 몇 가지 질문이 있습니다. 전체 목록은 다음과 같지만 기본적인 질문은 다음과 같습니다. 내 코드가 dealloc에 릴리스 메서드를 포함 할 수도 있고 포함하지 않을 수도 있지만 컴파일러는 합성 된 속성에 대한 ivar가 제대로 릴리스되었는지 어떻게 확인합니까?
참고 : 나는 그들이 너무 밀접하게 관련되어 있기 때문에 개별 질문으로이를 게시하지 않기로 결정 기존 질문의 소수가 있기 때문에 그 터치 정말 문제의 핵심에 점점없이 각각의 문제에.
다소 유사한 질문 :
설정 : 단일 속성이있는 클래스를 고려하십시오.
@interface Person : NSObject
{
NSString * name;
}
@property (nonatomic, retain) name;
@end
질문 # 1 : 아주 기본적인 경우 :
@implementation Person
@synthesize name;
@end
이 설정에서는 오브젝트가 해제 name
될 때마다 자동으로 해제 될 것이라고 가정합니다 Person
. 내 마음 속에서, 컴파일러는 단순히 삽입 [name release]
에 dealloc
내가 나 자신을 입력 한 것처럼 방법. 그 맞습니까?
질문 # 2 :dealloc
이 클래스에 대한 자체 메서드 를 작성하기로 선택 하고에 대한 호출을 생략하면 [name release]
누출이 발생합니까?
@implementation Person
@synthesize name;
- (void)dealloc { [super dealloc]; }
@end
질문 # 3 :dealloc
이 클래스에 대한 자체 메서드 를 작성하기로 선택하고에 대한 호출을 포함 하면 이미 처리되어 있으므로 [name release]
이중 릴리스 @synthesize
가 발생합니까?
@implementation Person
@synthesize name;
- (void)dealloc { [name release]; [super dealloc]; }
@end
질문 # 4 : 이 클래스에 대해 고유 한 속성 접근자를 작성하도록 선택했지만 고유 한 메서드를 작성 하지 않으면 유출됩니까?dealloc
name
@implementation Person
@dynamic name;
- (void)setName:(NSString *)newName
{
[newName retain];
[name release];
name = newName;
}
@end
질문 # 5 : 위의 시나리오 중 어느 것도 누출 또는 이중 릴리스를 초래하지 않을 것이라는 느낌이 있습니다 (경험을 기반으로 함) . 언어가이를 방지하도록 설계 되었기 때문입니다. 물론 그것은 "어떻게?"에 대한 질문을 제기합니다. 컴파일러는 가능한 모든 경우를 추적 할 수있을만큼 똑똑합니까? 다음을 수행하면 어떨까요 (이것은 내 요점을 설명하기위한 우스꽝스러운 예입니다).
void Cleanup(id object) { [object release]; }
@implementation Person
@synthesize name;
- (void)dealloc { Cleanup(name); }
@end
컴파일러가 다른 메소드 를 추가 [name release]
하도록 속 dealloc
일까요?
Q1 :
아니요 . 귀하를 위해 @synthesize
수정하지 않습니다 -dealloc
. 당신은에있는 자신.-release
name
Q2 :
네, 누출됩니다. Q1과 같은 이유입니다.
Q3 :
아니요, 이중 릴리스되지 않습니다. Q1과 같은 이유입니다.
Q4 :
네, 누출됩니다. Q1과 같은 이유입니다.
Q5 :
아니요, 이중 릴리스되지 않습니다. Q1과 같은 이유입니다.
당신은 재정 의하여이 자신을 확인할 수 있습니다 -retain
와 -release
와 -dealloc
에 무슨 일이 일어나고 있는지보고.
#import <Foundation/Foundation.h>
@interface X : NSObject {}
@end
@implementation X
-(oneway void)release {
NSLog(@"Releasing %p, next count = %d", self, [self retainCount]-1);
[super release];
}
-(id)retain {
NSLog(@"Retaining %p, next count = %d", self, [self retainCount]+1);
return [super retain];
}
-(void)dealloc {
NSLog(@"Dealloc %p", self);
[super dealloc];
}
@end
@interface Y : NSObject {
X* x;
}
@property (nonatomic, retain) X* x;
@end
@implementation Y
@synthesize x;
- (void)dealloc { [x release]; [super dealloc]; }
@end
int main () {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
Y* y = [[Y alloc] init];
X* x = [[X alloc] init];
y.x = x;
[y release];
[x release];
[pool drain];
return 0;
}
Q1, Q2 및 Q4에서, 마지막 -retainCount
의이 x
때문에이 누설이고, Q3 및 Q5는 마지막 1, -retainCount
0이고, -dealloc
그래서 누출이없는, 호출된다.
속성에 대한 Objective-C 문서에서 :
dealloc
Declared properties fundamentally take the place of accessor method declarations; when you synthesize a property, the compiler only creates any absent accessor methods. There is no direct interaction with the dealloc method—properties are not automatically released for you. Declared properties do, however, provide a useful way to cross-check the implementation of your dealloc method: you can look for all the property declarations in your header file and make sure that object properties not marked assign are released, and those marked assign are not released.
This essentially answers all your questions.
The simple and general rule: if you allocate, retain, or copy an object, YOU have to release it.
When you use the retain
setter semantic setting in a @synthesize
statement, you're asking the compiler to build for you a setter that calls retain
on the object. Nothing more, nothing less. And since you are retaining that object (even though it's via magically auto-generated code), you have to release it, and where to release it is in -(void)dealloc
.
Something else it's worth knowing - if you have a synthesised property, setting that property to nil (using dot syntax, of course) will release the ivar for you.
참고URL : https://stackoverflow.com/questions/2189919/how-is-release-handled-for-synthesized-retain-properties
'Nice programing' 카테고리의 다른 글
목록을 합산하는 데 mapToDouble ()이 정말로 필요합니까? (0) | 2020.11.18 |
---|---|
Apache Kafka에서 주제를 삭제하는 방법 (0) | 2020.11.18 |
이미지 주위에 텍스트를 배치하는 방법 (0) | 2020.11.18 |
Reactive Framework, PLINQ, TPL 및 Parallel Extensions는 서로 어떤 관련이 있습니까? (0) | 2020.11.17 |
RSpec에서 "any_instance" "should_receive"를 여러 번 말하는 방법 (0) | 2020.11.17 |