原文出處: talisk斯溫的技術博客(@swaIn ) 設計模式
在iOS中,全部的UIControl標準控件使用到最廣泛最傳統的執行方法的方式就是Target-Action,中文通常稱做目標-動做,是比較經常使用的一種設計模式。它的主要思想就是,在對象產生某個事件的特定時刻,給一個對象發送一個消息。就好像說『當talisk即將吃早飯的時候,swain去煎個蛋』。函數
其實Target-Action是很好用很方便的一個模式,但其最致命的一個缺點就是傳值很麻煩,本文總結下這種模式的傳值方式,並給出我認爲最好的一個傳值方式。atom
這是最簡單的一個方式,tag
是一個無符號整型值,貫穿於全部UIKit控件,給控件加上tag
,在action方法裏能夠取到sender
,對sender
作強制類型轉換便可拿到tag
。spa
Objective-C.net
1設計 |
[self.datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged];code |
Objective-Corm
1對象 2blog 3 4 5 |
- (void)dateChange:(id)sender { if (((UIDatePicker *)sender).tag) { NSLog(@"tag0"); } } |
因爲tag
是個無符號整型數值,也僅僅能傳遞一些簡單數據。
sender
就是發起行爲的對象,就像上面這段代碼所寫,當datePicker
的值發生變化的時候,調用self
的dateChange:
方法,這個方法默認參數就是sender
。
經過category給父類加上一些方法,使子類對象可以攜帶一些數據,這樣對於開發者來講就很自由了。
Objective-C
1 2 3 4 5 6 7 |
#import <Foundation/Foundation.h>
@interface NSObject (Extension)
@property (nonatomic,retain)NSDictionary *userInfo;
@end |
在頭文件中,註明category和名稱,加上咱們須要使用的數據的property。
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#import "NSObject+Extension.h" #import <objc/runtime.h>
@implementation NSObject (Extension)
- (void)setUserInfo:(NSDictionary *)_userInfo { objc_setAssociatedObject(self, @"userInfo", _userInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
- (id)userInfo { return objc_getAssociatedObject(self, @"userInfo"); }
@end |
在實現文件中,要用到Objective-C的Runtime黑魔法了,經過使用objc_getAssociatedObject
和objc_setAssociatedObject
兩個運行時函數的使用,動態地向NSObject
根類中添加了屬性,這樣,只要是繼承自NSObject
而且引用了這個Category的地方,咱們均可以給對象添加userInfo這個屬性,意味着咱們想傳遞什麼就能夠傳遞什麼了。
在寫完這個Category後,咱們在須要傳值的地方,給對象設置好userInfo,便可。
Objective-C
1 2 |
[self.datePicker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged]; [self.datePicker setUserInfo:@{@"from": [NSDate date], @"to": [NSDate date]}]; |
Objective-C
1 2 3 |
- (void)dateChange:(id)sender { NSLog(@"%@", ((UIDatePicker *)sender).userInfo); } |
QQ技術交流羣290551701