在ios開發中,咱們經常會用到相似例如如下的對話框:java
所以,例如如下這段代碼咱們也就很是熟悉了:ios
- (IBAction)showSheet:(id)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"title,nil時不顯示" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"肯定" otherButtonTitles:@"第一項", @"第二項",nil]; actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque; [actionSheet showInView:self.view]; }當中initWithTitle函數的第二個參數爲delegate,那麼是什麼呢? 咱們到它的頭文件裏看看。
initWithTitle這個函數的聲明例如如下 : 設計模式
- (id)initWithTitle:(NSString *)title delegate:(id<UIActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;是的,上面這個巨長無比的函數聲明就是initWithTitile函數,oc這個語言自己給個人感受就是繁雜。廢話很少說,咱們直接看到delegate參數的類型是id<UIActionSheetDelegate>。直接看UIActionSheetDelegate的聲明:
@protocol UIActionSheetDelegate <NSObject> @optional // Called when a button is clicked. The view will be automatically dismissed after this call returns - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; // Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button. // If not defined in the delegate, we simulate a click in the cancel button - (void)actionSheetCancel:(UIActionSheet *)actionSheet; - (void)willPresentActionSheet:(UIActionSheet *)actionSheet; // before animation and showing view - (void)didPresentActionSheet:(UIActionSheet *)actionSheet; // after animation - (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex; // before animation and hiding view - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation @end可以看到UIActionSheetDelegate是一個普普統統的協議,在@optional如下有六個函數,這些函數都是可選實現的,每個函數相應的是UIActionSheet中每個button的點擊事件處理。固然最後兩個函數是依照索引來區分Button對象的。
協議與delegate不是同一律念,協議是語言級別的特性,而delegate是藉助協議來的實現的一種設計模式,事實上就是代理模式。經過注入ide
代理對象實現對應的功能。函數
事實上它的主要功能也就是實現回調,與Java中的listener同樣。post
如下以一個演示樣例來講明 :this
// ButtonClickDelegate協議 @protocol ButtonClickDelegate <NSObject> -(void) onClick: (id) sender ; @end // view的聲明。實現了ButtonClickDelegate協議 @interface UIView : NSObject <ButtonClickDelegate > { @protected id<ButtonClickDelegate> clickDelegate ; } // 點擊事件代理。所以UIView實現了ButtonClickDelegate協議,所以本身可以爲本身代理。 @property (nonatomic, strong) id<ButtonClickDelegate> clickDelegate ; // 點擊view的觸發函數 -(void) performClick ; @end // view的實現 @implementation UIView @synthesize clickDelegate ; // 默認的點擊事件 -(id) init { self = [super init] ; if ( self ) { clickDelegate = self ; } return self; } // 點擊view的事件的默認處理 -(void) onClick: (id) sender { NSLog(@"點擊view的默認處理函數.") ; } // 點擊事件 -(void) performClick { [clickDelegate onClick: self ] ; } @end // ViewController聲明, 實現了ButtonClickDelegate協議,可以做爲UIView的代理 @interface ViewController : NSObject <ButtonClickDelegate> @property (nonatomic, strong) UIView* parenView ; @end // ViewController實現 @implementation ViewController -(void) onClick:(id)sender { NSLog(@"ViewController來實現點擊事件") ; } @endmain函數:
// main int main(int argc, const char * argv[]) { @autoreleasepool { // view對象 UIView* view = [[UIView alloc] init] ; [view performClick] ; // 構建一個ViewController對象 ViewController* controller = [[ViewController alloc] init] ; view.clickDelegate = controller ; [view performClick] ; } return 0; }
首先建立了一個UIView對象view, 而後調用performClick函數,此時view沒有設置delegate,但是由於本身實現了ButtonClickDelegate協議,所以可以爲本身代理該點擊事件。而後咱們建立了ViewController對象controller, 並且將該對象設置爲view對象的delegate。 而後運行performClick函數,此時在performClick函數中atom
會運行ViewController中的onClick函數。即controller代理了view的點擊事件處理。輸出結果例如如下 : spa
點擊view的默認處理函數. ViewController來實現點擊事件
delegate與Java中的Listener的功能大體是一樣的,比方咱們看看Android中一個button的點擊事件的處理。設計
Button mJumpButton = (Button) findViewById(R.id.button_jump); mJumpButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } });
當中的Button就至關於上文中的UIView,而其setOnClickListener就至關於delegate屬性的設置方法。OnClickListener就扮演了上文中ButtonClickDelegate的角色,
onClick方法更是一模一樣。事實上每個平臺大致上的設計思路也都是很是相近的,觀察不一樣平臺的對照實現更easy理解吧。
// 點擊事件代理,所以UIView實現了ButtonClickDelegate協議。所以本身可以爲本身代理。 @property (nonatomic, strong) id<ButtonClickDelegate> clickDelegate ;
注意這裏的類型是id<ButtonClickDelegate>;這代表該delegate對象可以是隨意類型,但是該類型必須實現ButtonClickDelegate協議,也可以說成該類型必須採用正式協議ButtonClickDelegate。這個就很是像Java中的泛型。好比咱們可以在Java中這樣使用泛型,
void setData(List<? extends Order> myorders) ;在setData函數中接受的參數爲元素類型爲Order子類的List集合,與id<ButtonClickDelegate>是否是又很是類似呢?