self
클래스 메서드를 참조 할 때 self
은 해당 클래스의 특정 인스턴스가 아니라 클래스 자체를 참조합니다. 이러한 클래스 메서드에서 실제 클래스 이름이 아닌 self
을 사용하면 문제가되는 클래스를 쉽게 서브 클래 싱 할 수 있습니다. 특히 클래스 메서드는 상속되지만 self
참조는 이제 기본 클래스가 아닌 하위 클래스를 참조합니다. 이름으로 기본 클래스를 참조하면 이는 사실이 아닙니다.
이 팩토리 메소드 고려 :
@implementation BaseClassObject
// THIS IS WRONG
+ (BaseClassObject *)object {
return [[BaseClassObject alloc] init];
}
@end
을 그리고이 서브 클래스 고려 : 문제는 그 object
팩토리 메소드 것입니다
SubClassObject *object = [SubClassObject object]; // WRONG
을 :
@interface SubClassObject : BaseClassObject
@end
그런 다음 수행하는 코드를 고려를가 아닌 BaseClassObject
을 반환하십시오.3210. 내가 [SubClassObject object]
를 참조 할 때
@implementation BaseClassObject
// THIS IS RIGHT
+ (instancetype)object {
return [[self alloc] init];
}
@end
지금, 나는 SubClassObject
보다는 BaseClassObject
의 인스턴스를 얻을 것이다 : 우리가 팩토리 클래스 메소드의 정의는 self
을 사용하여 변경하는 경우 그러나 그것은 해결할된다.
참고 : 내 인위적인 예, 그것은 self
을 사용하는 것이 오히려 중요합니다. 그래도 바로 관련성이없는 코드가있을 수 있습니다 (예 : 기본 클래스가 있지만 현재로서는 하위 클래스가 없을 수 있음).
심지어이 경우에도 "future-proof"코드에 관계없이이 클래스 메서드에서는 self
을 사용하는 습관이 있어야합니다. 따라서 예상치 못한 날짜에이 기본 클래스를 하위 클래스로 서브 클래 싱하는 경우 앞으로 이러한 클래스 메서드는 서브 클래 싱 된 경우에도 제대로 작동 할 가능성이 높습니다.
출처
2014-11-23 13:16:58
Rob
마지막 예제에서 "this is right"와 완전히 동의 할 수 없습니다. http://stackoverflow.com/a/26821507/2792531 – nhgrif
나는 실제적인 추가 구성이 init 메소드에 들어가는 것이 좋습니다. 팩토리 메서드는 그 결과를 반환합니다. – nhgrif
팩토리 메소드에 무엇이 들어가고'init'으로 들어가는 지에 대한 논의는 여기서는별로 관련이 없지만 여러분을 위해 그 주석을 제거했습니다. – Rob