2013-10-29 3 views
0

내 클래스 MyClassName에 정의 된 myPropertyName이라는 속성이 있다고 가정합니다. 수동 메모리 관리는이 게시물 전체에서 사용됩니다.초기화 된 속성 또는 인스턴스 변수

MyClassName.h

#import <UIKit/UIKit.h> 
@interface MyClassName : NSObject { 
    @private 
     NSObject* myPropertyName; 
    @public 
} 
@property (nonatomic, retain) NSObject* myPropertyName; 
// Some methods prototypes are here 
@end 

MyClassName.m

#import "MyClassName.h" 
@implementation MyClassName 
@synthesize myPropertyName; 
// Some methods are here 
@end 

I는 myPropertyName 선언 인스턴스 변수 사이의 차이의 장소 용도 혼동 해요. 예를 들어, 내 클래스 myClassName에 대한 사용자 정의 -(void)init 메소드에서와 같이이 세 가지 초기화 코드 문장 간의 차이점은 무엇입니까?

self.myPropertyName = [[[NSObject alloc] init] autorelease];

  1. 이 하나가 myPropertyName 세터를 호출,하지만 난 세터에서 사용되는 인스턴스 변수 존재의 이름이 무엇인지 확실하지 않다, myPropertyName는 (나는 @private 필드를 선언 한 이후 myPropertyName) 또는 _myPropertyName (언더 바를 가진 사람이 기본값이라고 사람들이 말했습니까?)

  2. myPropertyName = [[NSObject alloc] init];

    이는 myPropertyName 속성의 인스턴스 변수를 초기화합니까? @synthesize myPropertyName = _myPropertyName;이 없으면이 속성의 기본 인스턴스 변수가 _myPropertyName이라고합니다. 내가 @synthesize myPropertyName;@private NSObject* myPropertyName;를 사용 myPropertyName 경우에도

  3. _myPropertyName = [[NSObject alloc] init];

    _myPropertyName은 여전히 ​​내 재산의 인스턴스 변수로 선언되어 있습니까? 제 이해

는, 속성은 단지 이름 (예 myPropertyName 등) 등의 값을 할당 코드와 실제 작업에 사용되는 캡슐화 일부 인스턴스 변수가 있어야한다.

+3

더 이상'@ synthesize' 할 필요가 없습니다. 당신의 실제 질문 인 것처럼, 당신은 상응하는'ivar'없이'@ property'를 가질 수 있습니다. – nhgrif

답변

2

먼저 nhgrif로 연결된 Apple's documentation on properties을 읽는 것이 좋습니다. 그러나, 나는 문서가 조금 빽빽한 독서 자료가 될 수 있다는 것을 이해합니다. (Apple의 발견은 그렇게 나쁘지 않습니다.) 그래서 여기서 속성에 대해 간략하게 설명하겠습니다.

저는 예제가 좋으므로 두 클래스를 좀 더 최신 양식으로 다시 작성하려고합니다.

MyClassName.h

#import <UIKit/UIKit.h> 
@interface MyClassName : NSObject 

@property (nonatomic, strong) NSObject *myPropertyName; 
// method prototypes here 
@end 

MyClassName.m

#import "MyClassName.h" 
@implementation MyClassName 
// some methods here 
@end 

클래스 MyClassName 이제 유형 NSObject *myPropertyName라는 속성이 있습니다. 컴파일러는이 인스턴스에서 "무료"를 위해 많은 작업을 수행합니다. 구체적으로 보강 변수를 생성하고 myPropertyName에 대한 setter 및 getter를 생성합니다. 나는 두 파일을 다시 작성하고, 나는 그들이 같을 것이다, 그 물건을 포함, 컴파일러 해요 척한다면 :

MyClassName.h

#import <UIKit/UIKit.h> 
@interface MyClassName : NSObject { 
    NSObject *_myPropertyName; 
} 

@property (nonatomic, strong) NSObject *myPropertyName; 

- (void)setMyPropertyName:(NSObject *)obj; 
- (NSObject *)myPropertyName; 

@end 

MyClassName.m

#import "MyClassName.h" 
@implementation MyClassName 

- (void)setMyPropertyName:(NSObject *)obj 
{ 
    _myPropertyName = obj; 
} 

- (NSObject *)myPropertyName 
{ 
    return _myPropertyName; 
} 

@end 

다시 말하지만,이 모든 것이 "무료"로 진행되고 있습니다. 나는 그저 두려운 상황에서 일어나는 일을 보여주고 있습니다. 이제 번호가 매겨진 질문을 위해.

  1. 모든

    self.myPropertyName = [[[NSObject alloc] init] autorelease];

    먼저, 당신은 아마 자동 참조 횟수 또는 ARC를 사용해야합니다. 이 경우 autorelease으로 전화 할 수 없습니다. 그 부분을 무시하고,이 잘 작동합니다. autorelease을 제외하면 정확히 다음과 같습니다.

    [self setMyPropertyName : [[NSObject alloc] init]];

    당신은 내가 썼다 두 번째 .m 파일을 보면, 위, 기본적으로 변환합니다 어떤 :

    `_myPropertyName = [[NSObject의 ALLOC] 초기화] 이 클래스에 myPropertyName라는 어떤 변수가 없기 때문에

  2. 서면으로 myPropertyName = [[NSObject alloc] init];

    ,이 코드는 컴파일러 오류를 줄 것이다.당신은 정말 기본 인스턴스 변수에 액세스하려면 (또는, "백업")는 myPropertyName 재산을 수행 할 수 있습니다, 실제 이름 사용하여 :

    _myPropertyName = [[NSObject alloc] init]; // note the underscore

    그러나 대부분의 시간, 그것은을 사용하는 것이 좋습니다를 setter는 포인트 1에서와 같이 부작용과 키 - 값 코딩 (Key-Value Coding) 및 기타 좋은 것들을 허용합니다.

  3. _myPropertyName = [[NSObject alloc] init];

    오. 당신은 그것을 얻었습니다. 포인트 2.

를 참조하십시오 당신이 언급 :

나는 그런 myPropertyName 선언, 인스턴스 변수 사이의 차이의 장소로 용도와 혼란 스러워요. 예를 들어, 내 클래스 myClassName에 대한 사용자 정의 -(void)init 메소드에서와 같이이 세 가지 초기화 코드 문장 간의 차이점은 무엇입니까?

분명하지 않은 경우, 속성은 추상적 개념의 무언가이다; 그 데이터는 일반적으로 컴파일러에 의해 할당 된 일반 인스턴스 변수에 저장됩니다. 액세스는 일반적으로 setter 및 getter로 제한되어야하며 중요한 예외가 있습니다. 이 대답을 짧게 유지하기 위해, 나는 그 이상으로 자세하게 설명하지 않을 것입니다.

한 가지 더 : nhgrif가 언급 했으므로 더 이상 @synthesize 키워드를 사용할 필요가 없습니다. 이것은 현재 컴파일러가 암묵적으로 이해하고 있습니다.

확실하지 않은 경우 댓글을 달거나 더 잘 읽으려면 docs을 읽으십시오.

+0

이 문장에서 @Riley에게 "이 코드는이 클래스에 _myPropertyName이라는 변수가 없기 때문에 컴파일러 오류를 발생시킵니다. 실제로 (또는"backing ") 인스턴스 변수에 액세스하려면 실제 이름을 사용하면 myPropertyName 속성을 사용할 수 있습니다. "*이 클래스에는 ** myPropertyName' **이라는 변수가 없습니다. – Cong

+0

@conglu 나는 정말로했다. 그 점을 지적 해 주셔서 대단히 감사합니다. 내 대답이 편집되었습니다. – ravron

1

이의이 예제를 보자 : 구현에, 우리는 세터와 게터,이 세터와 게터에를 오버라이드 (override)하는 경우

@property NSString *fullName; 

, 우리는 인스턴스 변수 fullName를 사용하지 않는,이 작성되지 않습니다. 예를 들어,이 예에서,

- (NSString *)fullName 
{ 
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName]; 
} 

- (void)setFullName:(NSString *)fullName 
{ 
    //logic to split fullName into two strings 
    //self.firstName = etc 
    //self.lastName = etc. 
} 

생성 fullName 대한 인스턴스 변수가 없다. 그러나, 당신은 세터와 게터를 모두 오버라이드 (override)하지 않는 경우

Apple's Official Documentation

에 따라되고, 인스턴스 변수가 생성됩니다.

sidenote로 속성 readonly을 선언 한 다음 을 재정의하면 (변수를 사용하지 않고) ivar이 생성되지 않습니다. 마찬가지로 속성 writeonly을 선언하고 setter을 재정의 할 수 있습니다.

관련 문제