實現delegate鏈/廣播前端
Delegate是IOS中普通使用的設計模式,一般只能指定一級delegate。但有的時候,好比使用UITableView,若是業務比較複雜,每一個section有獨立的數據和展現方式,很天然的就會想到把不一樣的section邏輯封裝成不一樣的類,這時你可能就會但願每一個section有本身的delegate。而CYMDelegateChain剛好能幫你作這些事。git
CYMDelegateChain實現了delegate鏈,消息會在鏈上逐級傳遞,直到到達鏈表末尾,或者遇到實現了此消息的方法。默認狀況下,消息命中第一個方法後再也不向下傳遞,但能夠經過在被調用方法內執行CYMDelegateChainContinue(), 設置消息繼續向下傳遞。github
CYMDelegateChainInsert: 在鏈表前端插入delegate設計模式
//將section1插入列表前端 CYMDelegateChainInsert(self.dataSource, section1, self);
CYMDelegateChainRemove: 從鏈表中刪除已存在的delegate測試
//將section1從鏈表中刪除 CYMDelegateChainRemove(self.dataSource, section1, self);
CYMDelegateChainReplace: 從替換已存在的delegate
//將section1從鏈表中刪除spa
//將section1替換section2 CYMDelegateChainReplace(self.dataSource, section1, section2, self);
CYMDelegateChainContinue: 設置continue標誌,指定當前delegate方法返回後,當前調用結束後,繼續調用下一個Delegate,能夠實現廣播設計
CYMDelegateChainContinue();
爲便於說明,舉一個簡單的例子:利用CYMDelegateChain,將UITableView的section邏輯獨立開來。
下面是關鍵部分的代碼,完整代碼請下載源碼查看。code
封裝類,處理section數據事件
@interface TestTableViewSectionData : NSObject<UITableViewDataSource> @property NSInteger sectionId; @end @implementation TestTableViewSectionData - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (_sectionId == indexPath.section) { //只處理本section的消息 //做一些與本section相關的事情 ... return cell; }else{ //非本section的消息,交給其餘delegate處理 CYMDelegateChainContinue(); return nil; } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if (_sectionId == section) { //只處理本section的消息 //做一些與本section相關的事情 ... }else{ //非本section的消息,交給其餘delegate處理 CYMDelegateChainContinue(); return 0; } } @end
封裝類,處理TableView數據,如section數量ci
@interface TestTableViewData : NSObject<UITableViewDataSource> @property NSMutableArray* sections; @end @implementation TestTableViewData -(instancetype) init { self = [super init]; if(self){ _sections = [[NSMutableArray alloc]init]; } return self; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return _sections.count; } @end
擴展UITableView,方便對section的管理
@implementation UITableView(TestSection) /** 添加section,返回sectionid */ -(NSInteger) addTestSection:(TestTableViewSectionData*) section{ TestTableViewData*data = objc_getAssociatedObject(self, @"__testdata"); NSInteger sectionId = 0; if(!data){ data = [[TestTableViewData alloc]init]; objc_setAssociatedObject(self, @"__testdata", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); //在鏈中插入新section,只處理numberOfSectionsInTableView CYMDelegateChainInsert(self.dataSource, data, self); } sectionId = data.sections.count; section.sectionId = sectionId; //在鏈中插入新section,每一個section只處理本身的事件 CYMDelegateChainInsert(self.dataSource, section, self); [data.sections addObject:section]; return sectionId; } @end
操做UITableView,插入多個section
- (void)viewDidLoad { [super viewDidLoad]; //測試section TestTableViewSectionData* sec0 = [[TestTableViewSectionData alloc]init]; TestTableViewSectionData* sec1 = [[TestTableViewSectionData alloc]init]; TestTableViewSectionData* sec2 = [[TestTableViewSectionData alloc]init]; [_tabView addTestSection:sec0]; [_tabView addTestSection:sec1]; [_tabView addTestSection:sec2]; }
查看運行結果