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의 새로운 기능이라고 생각합니다.
Number 3 does not have those accessors generated so you have to write them yourself. If you want your accessor methods to have side effects, you do your standard memory management dance, as shown above, then do whatever side work you need to, inside the accessor method. If you synthesize a property as well as write your own, then your version has priority.
Did I cover everything?
Back in the old days you had ivars, and if you wanted to let some other class set or read them then you had to define a getter (i.e., -(NSString *)foo)
and a setter (i.e., -(void)setFoo:(NSString *)aFoo;
).
What properties give you is the setter and getter for free (almost!) along with an ivar. So when you define a property now, you can set the atomicity (do you want to allow multiple setting actions from multiple threads, for instance), as well as assign/retain/copy semantics (that is, should the setter copy the new value or just save the current value - important if another class is trying to set your string property with a mutable string which might get changed later).
This is what @synthesize
does. Many people leave the ivar name the same, but you can change it when you write your synthesize statement (i.e., @synthesize foo=_foo;
means make an ivar named _foo
for the property foo
, so if you want to read or write this property and you do not use self.foo
, you will have to use _foo = ...
- it just helps you catch direct references to the ivar if you wanted to only go through the setter and getter).
As of Xcode 4.6, you do not need to use the @synthesize
statement - the compiler will do it automatically and by default will prepend the ivar's name with _
.
'IT박스' 카테고리의 다른 글
파일에서 찾기에서 폴더를 제외하도록 Visual Studio에 지시하는 방법은 무엇입니까? (0) | 2020.10.06 |
---|---|
나중에 Jupyter (IPython) 노트북 세션을 피클하거나 저장하는 방법 (0) | 2020.10.06 |
C ++ 0x에서 변환 범위를 좁 힙니다. (0) | 2020.10.06 |
양식 POST에서 헤더 필드를 설정하는 방법은 무엇입니까? (0) | 2020.10.06 |
장고 신호 vs. 저장 방법 재정의 (0) | 2020.10.06 |