亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Objective-C中創建委托?

如何在Objective-C中創建委托?

iOS
紫衣仙女 2019-05-27 15:10:38
如何在Objective-C中創建委托?我知道代表們的工作方式,我知道如何使用它們。但是我該如何創建呢?
查看完整描述

3 回答

?
智慧大石

TA貢獻1946條經驗 獲得超3個贊

Objective-C委托是已將delegate另一個對象分配給屬性的對象。要創建一個,只需定義一個實現您感興趣的委托方法的類,并將該類標記為實現委托協議。

例如,假設你有一個UIWebView。如果你想實現它的委托webViewDidStartLoad:方法,你可以創建一個這樣的類:

@interface MyClass<UIWebViewDelegate>// ...@end@implementation MyClass- (void)webViewDidStartLoad:(UIWebView *)webView { 
    // ... }@end

然后,您可以創建MyClass的實例并將其指定為Web視圖的委托:

MyClass *instanceOfMyClass = [[MyClass alloc] init];myWebView.delegate = instanceOfMyClass;

另一方面UIWebView,它可能具有與此類似的代碼,以查看委托是否響應webViewDidStartLoad:消息respondsToSelector:并在適當時發送它。

if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
    [self.delegate webViewDidStartLoad:self];}

委托屬性本身通常聲明weak(在ARC中)或assign(預ARC)以避免保留循環,因為對象的委托通常持有對該對象的強引用。(例如,視圖控制器通常是它包含的視圖的委托。)

為您的類創建代表

要定義自己的委托,您必須在某處聲明其方法,如Apple Docs on protocols中所述。您通常會聲明一個正式的協議。從UIWebView.h轉述的聲明如下所示:

@protocol UIWebViewDelegate <NSObject>@optional- (void)webViewDidStartLoad:(UIWebView *)webView;// ... other methods here@end

這類似于接口或抽象基類,因為它為您的委托創建了一種特殊類型,UIWebViewDelegate在本例中。代表實施者必須采用該協議:

@interface MyClass <UIWebViewDelegate>// ...@end

然后實現協議中的方法。對于在協議中聲明的方法@optional(與大多數委托方法一樣),您需要-respondsToSelector:在調用特定方法之前進行檢查。

命名

委托方法通常以委托類名稱開頭命名,并將委托對象作為第一個參數。他們也經常使用意志,應該或形式。因此,webViewDidStartLoad:(第一個參數是Web視圖)而不是loadStarted(不帶參數)。

速度優化

每次我們想要給它發消息時,不是檢查委托是否響應選擇器,而是在設置委托時緩存該信息。一個非常干凈的方法是使用位域,如下所示:

@protocol SomethingDelegate <NSObject>@optional- (void)something:(id)something didFinishLoadingItem:(id)item;- (void)something:(id)something
 didFailWithError:(NSError *)error;@end@interface Something : NSObject@property (nonatomic, weak) id <SomethingDelegate>
  delegate;@end@implementation Something {
  struct {
    unsigned int didFinishLoadingItem:1;
    unsigned int didFailWithError:1;
  } delegateRespondsTo;}@synthesize delegate;- (void)setDelegate:(id <SomethingDelegate>)aDelegate {
  if (delegate != aDelegate) {
    delegate = aDelegate;

    delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
    delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
  }}@end

然后,在正文中,我們可以檢查我們的委托通過訪問我們的delegateRespondsTo結構來處理消息,而不是-respondsToSelector:一遍又一遍地發送。

非正式代表

協議出現之前,它是共同使用類別NSObject宣布委托可以實現的方法。例如,CALayer仍然這樣做:

@interface NSObject(CALayerDelegate)- (void)displayLayer:(CALayer *)layer;// ... other methods here@end

這基本上告訴編譯器任何對象都可以實現displayLayer:。

然后,您將使用與上述相同的-respondsToSelector:方法來調用此方法。代理只需實現此方法并分配delegate屬性,就是它(沒有聲明您符合協議)。這種方法在Apple的庫中很常見,但是新代碼應該使用上面更現代的協議方法,因為這種方法會污染NSObject(這使得自動完成功能不那么有用)并且使編譯器很難警告你有關拼寫錯誤和類似錯誤的信息。


查看完整回答
反對 回復 2019-05-27
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

當使用正式協議方法創建委托支持時,我發現您可以通過添加以下內容來確保正確的類型檢查(盡管是運行時,而不是編譯時):

if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
    [NSException raise:@"MyDelegate Exception"
                format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];}

在您的委托訪問器(setDelegate)代碼中。這有助于減少錯誤。


查看完整回答
反對 回復 2019-05-27
  • 3 回答
  • 0 關注
  • 741 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號