2012-01-13 8 views
4

이것은 상당히 복잡한 상속 계층이기 때문에 나와 함께 감당해야한다. (사용하고있는 정확한 사례를 언급하지 않고 단순화하려고 노력했다.) -Objective-C - 서브 클래스에있는 델리게이트의 서브 클래스

UITextField의 하위 클래스 인 TextField을 내 자신의 맞춤 확장 된 범용 텍스트 필드로 만듭니다. 이제이 향상된 기능을 제공하기 위해 TextField 메서드의 init 메서드에서 UITextField의 모든 대리 메서드가 TextField으로 전송되도록 super.delegate = self을 설정했습니다. TextFieldUITextFieldDelegate 프로토콜을 구현하고 흥미로운 작업을 수행하는 위임 메소드를 수신합니다.

그러나 차례로 나는 TextField자신의 대리인이되도록 만들고 싶습니다. 그래서 TextFieldDelegate이라는 새로운 프로토콜을 만들고 (UI -prefix가 없다는 것을 유의하십시오!) 다른 클래스가 TextField에서 대리자 메소드를 수신 할 수 있도록 TextField ivaya id<TextFieldDelegate> __weak delegate에 해당 속성을 지정합니다.

아직 너무 복잡하지 않으므로 계속 나와 함께 있기를 바랍니다. 하지만 이제는 TextField의 또 다른 사용자 정의 하위 클래스를 만들고이를 PasswordTextField이라고합니다 (실제로는 암호 기능을 구현하기 위해 서브 클래스를 만들지 않아도되지만 상당히 정교한 구현이 있다고 가정 해 봅시다. 그게 필요합니다).

PasswordTextField (TextField에 대리자 속성이있는 것처럼)이 향상된 대리자 메서드 집합을 보낼 수 있도록하려고한다고 가정 해 봅시다. 예를 들어 암호가 필요한 수준에 도달하면 전송되는 방법 passwordIsSecure을 보낼 수 있습니다. 이제 일반 TextField에없는이 동작 이후로 PasswordTextField에 대한 새 위임 메서드를 정의하는 PasswordTextFieldDelegate <TextFieldDelegate>TextField에 의해 전송 된 모든 대리자 메서드를 상속합니다.

문제는 다음과 같습니다. PasswordTextField에 어떻게 구현합니까? 작동하지 않는 것 : TextField의 위임 만에 TextFieldDelegate하지 PasswordTextFieldDelegate을 준수하기 때문에

상속

단순히, TextField에서 대리자를 상속 할 수 없습니다, 그래서 [delegate passwordIsSecure] 같은 방법을 보낼 수 없습니다 때문에 TextFieldDelegate에는 그러한 방법이 없습니다.

재정 바르

내가 대표라는 PasswordTextField에 바르를 선언 해 낼 수 있지만 컴파일러는 물론 슈퍼 클래스의 대표라는 아이바가 이미 있기 때문에이 중복 선언이라고 불평, 그래서

이 어느 쪽도 * 작동하지 않습니다.수정

슈퍼 클래스

나는 TextField 클래스로 돌아가서 구현하기 위해 대리자를 다시 정의 할 수 모두 TextFieldDelegatePasswordTextFieldDelegate,하지만이 지저분한 것하고, PasswordTextFieldDelegate 방법을 보낼 수 TextField을 알려줍니다의 물론, 그럴 수 없어!

나는이 책에서 모든 합리적인 코딩 규칙을 깨뜨린 것처럼 보이기 때문에 이것을 시도하지 않았습니다.

요약하면, 클래스의 서브 클래스가 슈퍼 클래스의 위임자의 하위 대리인이며이 모든 것이 잘 어울리는 것처럼 자신 만의 대리자를 가질 수있는 몇 가지 방법이 있어야합니다. 그걸 알아 내려고 하지마! 어떤 아이디어?

는 (* 측면의 문제로서, 나는 PasswordTextField는 "중복"바르라는 이름의 대리자를 선언 할 때 컴파일러가 불평 이유를 이해하지 않지만, TextField은 아마도 UITextField의 중복 인 바르라는 이름의 대리자를 선언 할 때 불평하지 않는다 대리자라는 속성!)

+0

은 어둠 속에서 타격 메신저있을 수 있습니다 ..하지만 당신은 단지 ID와 대리인의 @property를 다시 선언하고 자신의 합성이 경우 도움을 wouldnt? 나는 그것이 효과가있을 것이라고 생각한다. mebbe 아프다 잠시 후 시도하십시오. – govi

답변

1

UITextField 대리인 ivar의 이름은 대리자가 아니라 _delegate입니다. 따라서 TextField에서는 다시 선언 할 수 있지만 PasswordTextField에서는 다시 선언하지 않는 이유는 무엇입니까?

대리인 상속 문제입니다. ObjectiveC가 원하는 것을 지원하는지 잘 모르겠습니다.

'id <TextFieldDelegate>'대신 'id'대리인을 입력하기 만하면됩니다. 그런 다음 setDelegate를 재정의하고 delegate가 conformsToProtocol에 전달되도록 할 수 있습니다. 그러나 여기에서 컴파일 시간을 확인하지 않고 conformsToProtocol의 런타임 검사 만 사용하십시오

+0

_delegate 동작을 명확히 해 주셔서 감사합니다. 난 그냥 ID와 유형을 설정하는 것이 좋습니다 않았다 - 나는 가능한 솔루션을 내 목록에 포함하는 것을 잊었다하지만 당신이 말한대로 그것은 컴파일 시간 검사를 잃고, 그래서 더 나은 솔루션이 될 것이라고 생각했을 것이다? –

+0

글쎄, 두 세계에서 최고를 가질 수는 없다. (네가 할 수 있다고 생각지 않는다. 아마도 몇몇 언어가 더 좋을 것이다.) ..... 나는 자바에서 왔고, 강한 타입 안전을 놓쳤다. 처음에. 그러나 Objective-C는 Java보다 훨씬 유연하여이 작은 단점을 가지고 살 수 있으며이 언어의 다른 모든 위대함을 누릴 수 있습니다. 그러나, 실제로 뭔가를 줄 수없는 경우에만 'id'를 사용합니다. – bandejapaisa

+0

코드 예제를 얻을 수 있습니까? –

1

그래서, 거기에!

SimpleParent.h

@protocol Parentprotocol <NSObject> 

@end 

@interface SimpleParent : NSObject { 
    id<Parentprotocol> obj; 
} 

@property (retain) id<Parentprotocol> obj; 

@end 

에게 .. SimpleParent.m

#import "SimpleParent.h" 

@implementation SimpleParent 
@synthesize obj; 

@end 

SimpleChild.h

#import <Foundation/Foundation.h> 
#import "SimpleParent.h" 

@protocol SimpleChildProtocol <Parentprotocol> 


@end 

@interface SimpleChild : NSObject 

@property (assign) id<SimpleChildProtocol> obj; 

@end 

을 .. 작동뿐만 아니라 컴파일시 경고를 가지고 관리 SimpleChild.m

#import "SimpleChild.h" 

@implementation SimpleChild 
@synthesize obj; 

@end 
+1

SimpleChild가 SimpleParent에서 상속 할 때까지 작동합니다. 상속이 클래스와 프로토콜에서 동시에 작동하도록 작업하는 방법이 있습니까? – jowie

1

상당히 혼란스러운 질문입니다. 요점을 놓치면 용서해주세요. 그러나 3 가지 상속 레벨이 각기 다른 요구 사항을 가지고있는 것처럼 보입니다. 각 대리인은 다른 프로토콜을 준수해야합니다. 그렇다면 각 레벨의 대리인을 다른 이름의 ivar로 유지하고 다른 참조로 유지하는 해결책이 될까요?

예를 들어, 기본 클래스는 delegate이고 첫 번째 상속 하위 클래스에 할당됩니다. 여기에는 level1delegate이라는 자체 위임자가 있으며 그 다음 단계 인 level2delegate이라는 또 다른 대리인입니다. 물론이 객체가 세 가지 프로토콜 모두를 준수하면이 세 객체를 모두 같은 객체로 설정할 수 있습니다.

은 기본적으로, 그래서 그것을 깰하지 않으려 고 노력 떨어져 자신을 찢어하지 마십시오 대표는 "위임"이라고 할 수있다라고하는 규칙이 없습니다.

+0

나는 그가 이것을 할 수있게 해주는 다른 언어에 익숙하다고 생각한다. 예를 들어 Java에서는 인스턴스 변수를 특정 인터페이스 (예 : 프로토콜)로 선언 할 수 있으며 하위 클래스에서는 인스턴스 변수를보다 특수화 된 유형 (즉 인터페이스 확장)으로 재정의 할 수 있습니다. 그러나 Java는 강하게 static typed입니다. – bandejapaisa

+0

예, Objective-C로 개발하기 전에 저는 Java 개발자였습니다! –