iOS에서 합성 된 속성의 이름을 밑줄로 바꾸는 이유는 무엇입니까? [복제]
Xcode 4에서 새 프로젝트를 만들 때 상용구 코드는 구현 파일에서 ivar을 다음과 같이 합성 할 때 밑줄 문자를 추가합니다.
@synthesize window = _window;
또는:
@synthesize managedObjectContext = __managedObjectContext;
누군가 여기서 성취되고있는 것을 말해 줄 수 있습니까? 나는 완전한 nube가 아니지만 이것은 내가 이해하지 못하는 objective-C의 한 측면입니다.
혼란의 또 다른 지점; 응용 프로그램 위임 구현에서 위와 같이 창 iVar를 합성 한 후 응용 프로그램 didFinishLaunchingWithOptions : 메서드에서 window 및 viewController ivars는 self를 사용하여 참조됩니다.
self.window.rootViewController = self.viewController
[self.window makeKeyAndVisible];
그러나 dealloc 메소드에서는 _window 또는 _viewController입니다.
감사
이것은 Objective-C 런타임의 이전 버전의 결과입니다.
원래 @synthesize
는 접근 자 메서드를 만드는 데 사용되었지만 런타임에서는 인스턴스 변수를 명시 적으로 인스턴스화해야했습니다.
@interface Foo : Bar {
Baz *_qux;
}
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux = _qux;
- (void)dealloc {
[_qux release];
[super dealloc];
}
@end
사람들이 인스턴스 변수를 접두어 속성과 구별하기 위해 애플은 밑줄을 사용하지 않지만 다른 문제입니다. 인스턴스 변수를 가리 키도록 속성을 합성합니다. 그러나 요점은, _qux
인스턴스 변수이고 self.qux
(또는 [self qux]
메시지되는) qux
객체로 전송 self
.
인스턴스 변수를 직접 사용합니다 -dealloc
; 접근 자 메서드를 대신 사용하면 다음과 같이 보일 것입니다 (추천하지 않기 때문에 권장하지는 않지만).
- (void)dealloc {
self.qux = nil; // [self setQux:nil];
[super dealloc];
}
이는 qux
참조를 제로화 할뿐만 아니라를 해제하는 효과가 있습니다. 그러나 이것은 불행한 부작용을 가질 수 있습니다 :
- 예기치 않은 알림이 표시 될 수 있습니다.
qux
접근 자 메서드를 사용하여 변경 한 경우 기록되는 다른 객체의 변경 사항이 관찰 될 수 있습니다 . - (모든 사람이이 점에 동의하는 것은 아닙니다.) 접근자가 포인터를 제로화하면 프로그램에서 논리 오류를 숨길 수 있습니다. 객체 할당이 해제 된 후 객체의 인스턴스 변수에 액세스하는 중이라면 심각한 문제가있는 것입니다.
nil
그러나 Objective-C의 메시징 의미론으로 인해 접근자를로 설정 한 것을 알 수 없습니다nil
. 인스턴스 변수를 직접 해제하고 참조를 제로화하지 않은 경우 할당 해제 된 객체에 액세스하면 소리가 커EXC_BAD_ACCESS
집니다.
이후 버전의 런타임에는 접근 자 메서드 외에도 인스턴스 변수를 합성하는 기능이 추가되었습니다. 이러한 런타임 버전을 사용하면 인스턴스 변수를 생략하고 위의 코드를 작성할 수 있습니다.
@interface Foo : Bar
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux = _qux;
- (void)dealloc {
[_qux release];
[super dealloc];
}
@end
This actually synthesizes an instance variable on Foo
called _qux
, which is accessed by getter and setter messages -qux
and -setQux:
.
I recommend against this: it's a little messy, but there's one good reason to use the underscore; namely, to protect against accidentally direct ivar access. If you think you can trust yourself to remember whether you're using a raw instance variable or an accessor method, just do it like this instead:
@interface Foo : Bar
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux;
- (void)dealloc {
[qux release];
[super dealloc];
}
@end
Then, when you want to access the instance variable directly, just say qux
(which translates to self->qux
in C syntax for accessing a member from a pointer). When you want to use accessors methods (which will notify observers, and do other interesting things, and make things safer and easier with respect to memory management), use self.qux
([self qux]
) and self.qux = blah;
([self setQux:blah]
).
The sad thing here is that Apple's sample code and template code sucks. Never use it as a guide to proper Objective-C style, and certainly never use it as a guide to proper software architecture. :)
Here is another reason. Without underscoring instance variables you frequently obtain warning with the parameters self.title = title
and self.rating = rating
:
@implementation ScaryBugData
@synthesize title;
@synthesize rating;
- (id)initWithTitle:(NSString *)title rating:(float)rating {
if (self = [super init]) {
self.title = title; // Warning. Local declaration hides instance variable
self.rating = rating; // Warning. Local declaration hides instance variable
}
return self;
}
@end
You avoid warning by underscoring instance variables:
@implementation ScaryBugData
@synthesize title = _title;
@synthesize rating = _rating;
- (id)initWithTitle:(NSString *)title rating:(float)rating {
if (self = [super init]) {
self.title = title; // No warning
self.rating = rating; // No warning
}
return self;
}
@end
in the application didFinishLaunchingWithOptions: method the window and viewController ivars are referred to using self
No, they're not. Those are references to the properties window
and viewController
. That's the point of the underscore, to make it clearer when the property is being used (no underscore) and when the ivar is being accessed directly (with underscore).
Yes, Its is just to differentiate the reference of object. That is , if the object is referred directly use it with underscore, otherwise use self to refer the object.
'Programing' 카테고리의 다른 글
MSTest에서 여러 매개 변수로 테스트 방법을 실행하는 방법은 무엇입니까? (0) | 2020.07.06 |
---|---|
MyISAM과 InnoDB를 언제 사용해야합니까? (0) | 2020.07.06 |
FFmpeg로 이미지에서 비디오를 만드는 방법은 무엇입니까? (0) | 2020.07.06 |
R에 data.frame을 저장하는 방법? (0) | 2020.07.06 |
배열에서 스트림을 어떻게 만들 수 있습니까? (0) | 2020.07.06 |