之前發(fā)現(xiàn)了一種類似block串行執(zhí)行的開發(fā)方式,今天終于不忙了就簡單寫一下做個筆記
鏈式調用
其實很簡單,需要注意的就是相應對象的返回值,如下拿 person 和boy兩個對象舉例,最后實現(xiàn) person.person(NO).strongMan(@"強壯的小男孩").boy(@"小男孩兒開始說").speak(@"我想回家");
Person.h
#import <Foundation/Foundation.h>
@class Boy;
@interface Person : NSObject
@property (nonatomic,readonly) Person *(^person)(BOOL enable);
@property (nonatomic,readonly) Person *(^strongMan)(NSString *str);
@property (nonatomic,readonly) Boy *(^boy)(NSString *str);
@end
Person.m
#import "Person.h"
#import "Boy.h"
@implementation Person
-(Person *(^)(BOOL))person{
return ^(BOOL enable){
NSLog(@"Person Say:%d\n",enable);
return self;
};
}
-(Person *(^)(NSString *))strongMan{
return ^(NSString *str){
NSLog(@"%@\n",str);
return self;
};
}
-(Boy *(^)(NSString *))boy{
return ^(NSString *str){
NSLog(@"%@\n",str);
return [[Boy alloc]init];
};
}
@end
boy.h
#import <Foundation/Foundation.h>
@interface Boy : NSObject
@property (nonatomic,readonly)Boy *(^speak)(NSString *speakStr);
@end
boy.m
#import "Boy.h"
@implementation Boy
-(Boy *(^)(NSString *))speak{
return ^(NSString *speakStr){
NSLog(@"speak:%@\n",speakStr);
return self;
};
}
@end
vc調用--------------------------------------------------
- (void)viewDidLoad {
[super viewDidLoad];
person.person(NO).strongMan(@"強壯的小男孩").boy(@"小男孩兒開始說").speak(@"我想回家");
}
打印結果
一般的使用到此就結束了,下面來稍微加點難度,前面的我們都看到了,都是正向傳值,都是調用方直接告訴被調用方要干什么什么,那么我們如果需要調用方回傳一些數(shù)據(jù)做處理呢,大家自己思考一下再往下看
思路是這樣的,既然要反向且又想鏈式,那么自然想到了block,我們在被調用方的參數(shù)中修改參數(shù)為block是否能實現(xiàn)呢,繼續(xù)往下看
拿系統(tǒng)定位功能CLLocationManager來做例子,調用定位,我們首先要檢查權限、設置參數(shù)、開始定位、然后定位代理成功回調處理、失敗處理這幾個功能,我們最終的實現(xiàn)結果需要是這樣的
self.locationManager.checkAuthorization(NO).startLocation().locationSuccess(^(NSDictionary *addressDict) {
NSLog(@"定位成功");
}).locationError(^(NSError *error){
NSLog(@"定位失敗");
});
1.首先我們聲明這幾個block
###JoyLocationManager.h
@property (nonatomic,readonly)JoyLocationManager *(^checkAuthorization)(BOOL backGroundModel);
@property (nonatomic,readonly)JoyLocationManager *(^startLocation)();
@property (nonatomic,readonly)JoyLocationManager *(^stopLocation)();
//參數(shù)為idblock類型(我這是定義的id類型參數(shù)的回調)
@property (nonatomic,copy)JoyLocationManager *(^locationSuccess)(IDBLOCK block);
//參數(shù)為idblock類型(我這是定義的error類型參數(shù)的回調)
@property (nonatomic,copy)JoyLocationManager *(^locationError)(ERRORBLOCK block);
2.這幾個block
###JoyLocationManager.m
#pragma mark 檢查權限
-(JoyLocationManager *(^)(BOOL))checkAuthorization{
return ^(BOOL backGroundModel){
[self checkAuthorStateAndSetBackModel:backGroundModel];//檢查權限并設置是否后臺運行模式
return self;
};
}
#pragma mark 開始定位
-(JoyLocationManager *(^)())startLocation{
return ^(){
[self startManagerLocation];//開始定位
return self;
};
}
#pragma mark 結束定位
-(JoyLocationManager *(^)())stopLocation{
return ^(){
[self stopManagerLocation]; //結束定位
return self;
};
}
#pragma mark 定位成功
-(JoyLocationManager *(^)(IDBLOCK block))locationSuccess{
return ^(IDBLOCK block){
//runtime關聯(lián)對象,定位成功代理中回調參數(shù)
objc_setAssociatedObject(self, _cmd, block, OBJC_ASSOCIATION_COPY);
return self;
};
}
#pragma mark 定位失敗
-(JoyLocationManager *(^)(ERRORBLOCK))locationError{
return ^(ERRORBLOCK block){
//runtime關聯(lián)對象,定位失敗代理中回調參數(shù)
objc_setAssociatedObject(self, _cmd, block, OBJC_ASSOCIATION_COPY);
return self;
};
}
#pragma mark 定位代理
//CLLocation這個類里面包括的一些常用的位置信息有經度、緯度、海拔、速度、精確度
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
//定位成功進行地理反編碼,可以改進一下考慮自行加入到鏈中
[self reverseGEOCodeLocation:locations.firstObject];
[self stopManagerLocation];
}
//定位失敗
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
//拿到前面關聯(lián)的block并回調參數(shù)
ERRORBLOCK successBlock = objc_getAssociatedObject(self, @selector(locationError));
successBlock?successBlock(error):nil;
}
//反地理編碼
- (void)reverseGEOCodeLocation:(CLLocation *)location{
CLGeocoder *revGeo = [[CLGeocoder alloc] init];
[revGeo reverseGeocodeLocation:location
completionHandler:^(NSArray *placemarks, NSError *error) {
if (!error && [placemarks count] > 0)
{
NSDictionary *dict =
[[placemarks objectAtIndex:0] addressDictionary];
IDBLOCK successBlock = objc_getAssociatedObject(self, @selector(locationSuccess));
successBlock?successBlock(dict):nil;
}else{
NSLog(@"ERROR: %@", error);
}
}];
}
到此可以試試了
self.locationManager.checkAuthorization(NO).startLocation().locationSuccess(^(NSDictionary *addressDict) {
NSLog(@"定位成功");
}).locationError(^(NSError *error){
NSLog(@"定位失敗");
});
成功回走成功的回調,失敗會走失敗的回調,大家可以自行去試試把定位精度、headupdate、地理編碼等試試加進來