[英]Objective-C — Subclass of delegate in subclass
這是一個相當復雜的繼承層次結構,所以忍受我(我試圖簡化事情,而不是陳述我使用的確切情況,這更復雜): -
假設我創建了一個名為TextField
的UITextField
子類,它是我自己的自定義增強通用文本字段。 現在,為了提供這種增強功能,在TextField
的init
方法中,我設置了super.delegate = self
以便將UITextField
中的所有委托方法發送到TextField
。 TextField
實現UITextFieldDelegate
協議並接收這些委托方法以執行一些有趣的操作。
但是,反過來,我想讓它成為TextField
擁有它自己的委托。 所以我創建了一個名為TextFieldDelegate
的新協議(注意缺少UI
-prefix!),並為TextField
一個具有相應屬性的ivar id<TextFieldDelegate> __weak delegate
,以便其他類可以從TextField
接收委托方法。
我希望你還和我在一起,因為到目前為止我還沒有做過任何太復雜的事情。 但是讓我們說現在,我創建另一個TextField
自定義子類,讓我們稱之為PasswordTextField
(在現實生活中,人們可能不需要創建一個子類來實現密碼功能,但讓我們假設有一些相當復雜的實現這需要這個)。
讓我們假設我想讓它成為PasswordTextField
(類似TextField
具有委托屬性)能夠發送一組增強的委托方法。 例如,也許它可以發送一個方法passwordIsSecure
,一旦密碼達到所需的復雜程度就會發送該方法。 現在,由於在常規TextField
找不到這種行為,我創建了一個新協議: PasswordTextFieldDelegate <TextFieldDelegate>
,它定義了PasswordTextField
的新委托方法, 並繼承了TextField
發送的所有委托方法。
問題是:我如何在PasswordTextField
實現它? 不起作用的事情:
遺產
我不能簡單地從TextField
繼承委托,因為TextField
的委托只符合TextFieldDelegate
而不是PasswordTextFieldDelegate
,所以我不能發送像[delegate passwordIsSecure]
這樣的方法,因為TextFieldDelegate
沒有這樣的方法。
壓倒伊娃
我可以嘗試在PasswordTextField
聲明一個名為delegate的ivar,但編譯器抱怨這是一個重復的聲明,因為當然在超類中已經有一個名為delegate的ivar,所以這也不起作用*。
修改超類
我可以回到TextField
類並重新定義委托以實現TextFieldDelegate
和 PasswordTextFieldDelegate
,但這看起來很亂並且告訴TextField
它可以發送PasswordTextFieldDelegate
方法,當然,它不能!
我沒有試過這個,只是因為它似乎打破了書中所有合理的編碼規則。
總而言之,必須有一些方法來做到這一點,這樣一個類的子類可以擁有它自己的委托,它是超類委托的子委托,並且所有這些都可以很好地融合在一起,但我無法理解它出來了! 有任何想法嗎?
(*作為一個副作用,我不明白為什么編譯器會在PasswordTextField
聲明一個名為delegate的“重復”ivar時抱怨,但是當TextField
聲明一個名為delegate的ivar時,它不會抱怨,這可能是UITextField
屬性的副本代表!)
UITextField委托ivar名為_delegate,而不是委托。 因此,為什么你在TextField中再次聲明它,但在PasswordTextField中卻沒有。
至於你的委托繼承問題。 我不確定ObjectiveC是否支持你想要的東西。
您可能只需要鍵入您的委托'id',而不是'id <TextFieldDelegate>'。 然后你可以覆蓋setDelegate並確保委托傳遞conformsToProtocol。 但是,您將丟失此處的編譯時檢查,並且僅對conformsToProtocol進行運行時檢查
所以,那里! 工作..並設法有編譯時警告..
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
這是一個相當令人困惑的問題,所以請原諒我,如果我錯過了這一點,但看起來你的三個不同的繼承級別每個都有不同的委托要求,每個代表都必須遵循不同的協議,所以它會是一個解決方案,將每個級別的委托作為一個不同名稱的ivar,並作為一個不同的參考?
例如,您的基類將具有其delegate
,您已決定將其分配給第一個繼承的子類。 它有自己的委托,名為level1delegate
,下一級別有另一個委托,名為level2delegate
。 如果該對象符合所有三個協議,您當然可以將所有這三個設置為同一個對象。
基本上,沒有規則說代表必須被稱為“代表”,所以不要因為不打破它而撕裂自己。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.