2014-10-07 7 views
3

하위 클래스로 확장 할 기본 (또는 "추상") 클래스 역할을하는 클래스를 만들고 싶습니다. 내가 말하는 것에 대해 설명 할 수있는 가장 좋은 방법은 몇 가지 예를 든다는 것입니다. 여기 내 상위 클래스에 대한 가능한 인터페이스입니다 :"Modern"Objective-C의 합성 및 보호 된 인스턴스 변수?

#import <Cocoa/Cocoa.h> 
#import "MyViewControllerDelegate.h" 

@interface MyViewController : NSViewController 

@property (nonatomic, weak) id<MyViewModeControllerDelegate> delegate; 
@property (nonatomic, copy) NSArray *content; 

@end 

그 좋은 깨끗한 것처럼 작성,하지만 난 내 서브 클래스에서 인스턴스 변수에 액세스 할 수 없습니다.

몇 가지 연구를하고 후에, 나는 서브 클래스를 볼 수 있도록 인스턴스 변수에 직접 액세스 할 수있는 서브 클래스를 제공 할 수있는 좋은 방법은 @protected 지시어를 사용하여 헤더 파일에서 선언을 포함하는 것입니다 결론을 내렸다했습니다

#import <Cocoa/Cocoa.h> 
#import "MyViewControllerDelegate.h" 

@interface MyViewController : NSViewController { 
@protected 
    __weak id<MyViewControllerDelegate> _delegate; 
    NSMutableArray *_content; 
} 

@property (nonatomic, weak) id<BSDViewModeControllerDelegate> delegate; 
@property (nonatomic, copy) NSArray *content; 

@end 

저는 개인적으로 그 문제가 없으며 원하는 방식으로 작동합니다 (예 : 하위 클래스가 직접 ivars에 액세스 할 수 있지만 다른 클래스는 접근자를 사용해야 함). 그러나 인스턴스 변수가 합성되어야한다고 말하는 블로그 게시물이나 Stack Overflow 답변을 매일 읽거나 "인스턴스 변수를 더 이상 만지지는 않습니다."

문제는 Objective-C 이후 ARC를 배우기 시작한 것이므로 개발자가 과거에해야 할 일을 완전히 인식하지 못했습니다. 나는 개인적으로 getters/setter를 구현할 때 컨트롤을 좋아하고 실제로는 가능하다는 것을 좋아한다. 인스턴스 변수 선언을 참조하고 싶지만 어쩌면 나는 오래된 학교 다. 제 말은 "컴파일러가 인스턴스 변수를 합성하게 만하면"KVO를 구현하지 않고 어떤 종류의 논리 또는 "부작용"을 어떻게 포함할까요?

예를 들어, 내 인스턴스 변수와 getters/setters가 합성되어 있다면, 어떻게 지연 시간을 초기화합니까?

- (NSArray *)myLazyArray 
{ 
    if (_myLazyArray == nil) { 
     self.myLazyArray = @[]; 
    } 
    return _myLazyArray.copy; 
} 

을 또는 어떻게 내가 설정되는 값이 현재 설정된 값과 동일하지 있는지 확인 않습니다 예를 들어, 가끔 이렇게 하시겠습니까? 가끔 이런 내 mutator 메소드에 체크 구현하는 것이다 : 나는 애플의 문서를 모두 읽은

- (void)setMyLazyArray:(NSArray *)array 
{ 
    if ([array isEqualToArray:_myLazyArray]) 
     return; 
    _myLazyArray = array.mutableCopy; 
} 

을하지만, 절반 워드 프로세서 (경우에 따라서 또는 악화) 다시 2008 날짜, 그래서 난 문제에 대한 정보를 얻을 수있는 가장 좋은 장소라고 확신하지 못합니다.

내 질문의 요지 같아요 : Objective-C에서 인스턴스 변수, 변수 합성, 상속, 범위 등을 처리하는 "현대적인"방식이 선호됩니까? "Bro, Swift."가 포함되지 않은 답변에 대한 보너스 포인트 또는 "스위프트를 사용하지 않습니까?"

모든 안내를 주시면 감사하겠습니다. 읽어 주셔서 감사합니다!

+0

문제가 무엇인가?당신은 ivars _and_ 맞춤 getters/setters 합성 수 있습니다 –

+0

@ BryanChen 그래, 알아. 내 모든 문제는 내가 단지 "올바른"방식으로 뭔가하고 싶다는 것입니다. 또는 나는 그것을 "현대적인"방식으로 다시 말해야한다. 너무 자주 나는 내가 뭔가를 올바르게하고 있다고 생각한다. 단지 내가하고있는 방식이 비추천 또는 이와 유사한 것으로 계획되어 있음을 알기 위해서이다. 예를 들어, @synthesize myVar = _myVar'를 사용했습니다. 갑자기, 나는 더 이상 그렇게 할 필요가 없었다. 필자가 directive없이 getter *와 setter를 구현한다면, 나는 경고를 좌우로 받는다. 따라서, 결국'@ synthesize'를 추가하거나 ivar을 추가해야합니다. 그것은 나를 혼란스럽게합니다. –

+0

_all_ 접근자를 구현 한 경우에는 @synthesize myVar = _myVar' _only_가 필요합니다. (getter 및 setter for readwrite, readterly getter) –

답변

2

하위 클래스가 왜 당신의 ivars에 액세스해야합니까? Ivars는 구현 세부 사항이며 하위 클래스는이를 염려해서는 안됩니다. 부모 클래스가 속성 setter/getters에서 논리를 수행하는 경우 모든 종류의 부작용이있을 수 있습니다. 따라서 항상 속성을 통해 액세스하십시오.

이 하위 클래스에 가정 당신은 부동산 게터 재정의 : 세터에 대한

- (NSArray *)myLazyArray 
{ 
    if (super.myLazyArray == nil) { 
     // do what you need to do to populate the array 
     // assign it to yourself (or super) 
     self.myLazyArray = @[]; 
    } 

    return super.myLazyArray; 
} 

그리고 다음을 :

- (void)setMyLazyArray:(NSArray *)array 
{ 
    if ([array isEqualToArray:super.myLazyArray]) 
     return; 
    super.myLazyArray = array.mutableCopy; 
} 
+0

일반적으로 ivar에 대한 액세스가 필요한 유일한 이유는 복사 (속성을 통해 컬렉션을 가져올 때 발생)와 함께 발생하는 오버 헤드없이 빠르게 변경할 수있는 컬렉션으로 작업하는 것입니다. 복사 작업이 비쌀 수 있다고 가정 할 때 나는 틀린가? 저는 항상 가변 배열의 멤버에 대한 직접 액세스가 전체를 복사하여 멤버에 액세스하는 것보다 낫다고 생각했습니다. 아마이 모든 것을 지나치다. –

+0

글쎄, 처음부터 부동산에서 사본을 돌려 보내지 말아야한다. 발신자는 사본이 필요한지 여부를 결정해야합니다. 나는 솔직히 왜 처음부터 재산을 적절히 사용하여 지브 물성을 복사 한 이유를 생각할 수 없는지를 생각해 볼 수 있습니다. –

+0

복사본을 반환 할 계획이라면 분명히 명명 된 방법이어야한다고 생각합니다. 그냥 제 생각이지만 :) –