[objective-c] Objective-C에서 ivar와 속성의 차이점은 무엇입니까?

Objective-C에서 ivar와 속성을 사용하는이 세 가지 방법의 의미 론적 차이는 무엇입니까?

1.

@class MyOtherObject; 
@interface MyObject {
}
@property (nonatomic, retain) MyOtherObject *otherObj;

2.

#import "MyOtherObject.h"
@interface MyObject {
    MyOtherObject *otherObj;
}
@property (nonatomic, retain) MyOtherObject *otherObj;

삼.

#import "MyOtherObject.h"
@interface MyObject {
    MyOtherObject *otherObj;
}



답변

1 번은 컴파일러와 링커가 보는 코드의 양을 최소화하고 잠재적으로 순환 참조를 피하기 위해 MyOtherObject 클래스를 정방향 선언함으로써 다른 두 개와 다릅니다. 이렇게하면 #import를 .m 파일에 넣어야합니다.

@property를 선언하고 (및 .m에서 @synthesize와 일치) 파일을 지정하는 방식으로 처리 된 메모리 의미 체계와 함께 접근 자 메서드를 자동 생성합니다. 대부분의 객체에 대한 경험 규칙은 Retain이지만 NSStrings는 예를 들어 Copy를 사용해야합니다. Singleton과 Delegates는 일반적으로 Assign을 사용해야합니다. 손으로 쓰는 접근자는 지루하고 오류가 발생하기 쉬우므로 많은 입력 및 멍청한 버그를 줄일 수 있습니다.

또한 합성 된 속성을 선언하면 다음과 같은 점 표기법을 사용하여 접근 자 메서드를 호출 할 수 있습니다.

self.otherObj = someOtherNewObject; // set it  
MyOtherObject *thingee = self.otherObj; // get it 

일반적인 메시지 전달 방식 대신 :

[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it 

이면에서 실제로 다음과 같은 메서드를 호출합니다.

- (void) setOtherObj:(MyOtherObject *)anOtherObject {

    if (otherObject == anOtherObject) {
        return;
    }

    MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
    otherObject = [anOtherObject retain]; // put the new value in  
    [oldOtherObject release]; // let go of the old object
} // set it

…아니면 이거

- (MyOtherObject *) otherObject {
    return otherObject;
} // get it

엉덩이에 전체적인 통증이 있습니다. 이제 수업의 모든 ivar 에 대해 수행 하십시오. 정확하게하지 않으면 메모리 누수가 발생합니다. 컴파일러가 작업을 수행하도록하는 것이 가장 좋습니다.

나는 것을 볼 수 1 바르가 없습니다. 오타가 아니라고 가정하면 @property / @synthesize 지시문이 배후에서 ivar도 선언하므로 괜찮습니다. 나는 이것이 Mac OS X-Snow Leopard 및 iOS4의 새로운 기능이라고 생각합니다.

3 번 에는 이러한 접근자가 생성되지 않았으므로 직접 작성해야합니다. 접근 자 메서드에 부작용이 생기도록하려면 위에 표시된대로 표준 메모리 관리 댄스를 수행 한 다음 접근 자 메서드 내에서 필요한 모든 부수 작업을 수행합니다. 당신이 재산을 합성하는 경우 뿐만 아니라 자신을 작성할 때 , 다음 당신의 버전이 우선합니다.

내가 모든 걸 다뤘나요?


답변

예전에는 ivar가 있었고 다른 클래스가 설정하거나 읽도록하려면 getter (예 : -(NSString *)foo)및 setter (예 :))를 정의해야했습니다 -(void)setFoo:(NSString *)aFoo;.

당신에게 제공하는 속성은 ivar와 함께 무료로 (거의!) setter 및 getter입니다. 따라서 지금 속성을 정의 할 때 원 자성 (예 : 여러 스레드에서 여러 설정 작업을 허용 하시겠습니까?)을 설정할 수있을뿐만 아니라 의미 체계를 할당 / 유지 / 복사 할 수 있습니다 (즉, setter가 새 값을 복사해야하는 경우). 또는 현재 값을 저장하십시오. 다른 클래스가 나중에 변경 될 수있는 변경 가능한 문자열로 문자열 속성을 설정하려는 경우 중요합니다.)

이것이하는 일 @synthesize입니다. 많은 사람들이 바르 이름을 동일하게두고, 그러나 당신이 당신의 합성 문을 (즉, 쓸 때 당신은 그것을 변경할 수 있습니다 @synthesize foo=_foo;수단이라는 바르하게 _foo재산에 대한을 foo읽거나이 속성을 작성하려는 그렇다면, 당신은 사용하지 않는 self.foo, 당신은 것입니다 사용해야 _foo = ...합니다. setter와 getter 만 사용하려는 경우 ivar에 대한 직접 참조를 포착하는 데 도움이됩니다.

Xcode 4.6 @synthesize부터는 명령문 을 사용할 필요가 없습니다 . 컴파일러가 자동으로 수행하고 기본적으로 ivar의 이름 앞에 _.


답변