Nice programing

@synthesized 유지 속성에 대한 릴리스는 어떻게 처리됩니까?

nicepro 2020. 11. 18. 21:26
반응형

@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 : 이 클래스에 대해 고유 한 속성 접근자를 작성하도록 선택했지만 고유 한 메서드를 작성 하지 않으면 유출됩니까?deallocname

@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. 당신은에있는 자신.-releasename

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, -retainCount0이고, -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

반응형