学习OC下的链式编程实战
简单实现
BBPerson.h
#import
@class BBPerson;
typedef BBPerson *(^BBChainStringBlock)(NSString *);
@interface BBPerson : NSObject
@property (nonatomic, strong) NSString *nameString;/**< */
@property (nonatomic, strong) NSString *ageString;/**< */
- (BBChainStringBlock)name;
- (BBChainStringBlock)age;
@end
BBPerson.m
#import "BBPerson.h"
@implementation BBPerson
- (BBChainStringBlock)name {
BBChainStringBlock block = ^(NSString * aString) {
_nameString = aString;
return self;
};
return block;
}
- (BBChainStringBlock)age {
BBChainStringBlock block = ^(NSString * aString) {
_ageString = aString;
return self;
};
return block;
}
@end
使用例子
BBPerson *person = [BBPerson new];
// 使用方式可以如下:
person.age(@"18");
person.name(@"XXX");
person.name(@"XXX").age(@"18");
person.age(@"18").name(@"XXX");
NSLog(@"nameString=%@ ageString=%@",person.nameString,person.ageString);
// 解析:
// 其实person.name返回一个block,
BBChainStringBlock nameBlock = person.name;
nameBlock(@"XXX");// 这个block就是把 _nameString = @"XXX"; return self;
nameBlock(@"XXX").age(@"18");// nameBlock(@"XXX")是返回self,即使person对象,所以可以链式编程
增加一个make方法
+ (BBPerson *)makeConstraints:(void(^)(BBPerson *))block {
BBPerson *person = [[BBPerson alloc] init];
block(person);
return person;
}
使用make方法
// 就这么new一个person实例了
BBPerson *person = [BBPerson makeConstraints:^(BBPerson *maker) {
maker.name(@"WWW").age(@"18");
}];
// 以后需要括展属性,比如性别sex,写好sex的block
BBPerson *person1 = [BBPerson makeConstraints:^(BBPerson *maker) {
maker.name(@"WWW").age(@"18").sex(@"男");
}];
真实项目开发过程中,为了避免第三方库入侵项目代码内部,经常需要进一步封装第三方库:
1.项目与第三方尽量解耦,
2.使用、修改替换方便。
OC的封装就是各种条件都写好,参数少还可以,参数多封装的方法就多。
比如封装一下MBProgressHUD:动画参数、时间参数、显示的文字、显示在哪个view上、显示自定义的小图片、能不能操作hud背后界面。如果把这些参数都各种全组合方法一个一个写,那要死人哦。
// 一般的show,有各种组合、有maskType--能操作、不能操作
+ (void)show;
+ (void)showWithMaskType:(PSProgressHUDMaskType)maskType;
+ (void)showWithStatus:(NSString*)status;
+ (void)showWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress;
+ (void)showProgress:(float)progress maskType:(PSProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress status:(NSString*)status;
+ (void)showProgress:(float)progress status:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showInfoWithStatus:(NSString*)status;
+ (void)showInfoWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showSuccessWithStatus:(NSString*)status;
+ (void)showSuccessWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showErrorWithStatus:(NSString*)status;
+ (void)showErrorWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showStatus:(NSString*)status;
+ (void)showStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showImage:(UIImage*)image status:(NSString*)status;
+ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
如果使用链式编程,就可以解决参数过多的麻烦了。
然后自己试着用链式编程方式,封装一下MBProgressHUD
直接上代码
MBProgressHUD.h
#import
#import "MBProgressHUD.h"
#define kPSProgressHUD [PSProgressHUD new]
typedef NS_ENUM(NSUInteger, PSHUDMaskType) {
PSHUDMaskType_None = 0, //允许操作其他UI
PSHUDMaskType_Clear, //不允许操作
};
typedef NS_ENUM(NSUInteger, PSHUDInViewType) {
PSHUDInViewType_KeyWindow = 0, //UIApplication.KeyWindow
PSHUDInViewType_CurrentView, //CurrentViewController.view
};
typedef NS_ENUM(NSUInteger, PSProgressType) {
PSProgressType_HorizontalBar = 0, //水平进度条
PSProgressType_AnnularBar, //环形进度条
};
//PSProgressHUD链式编程语法的使用
/*
一、Loading
显示:[PSProgressHUD showLoadingCalculators:^(PSProgressHUD *make) {
make.inViewType(PSHUDInViewType_CurrentView).message(@"你好吗?");
}];
消失:[PSProgressHUD cancelLoadingCalculators:^(PSProgressHUD *make) {
make.inViewType(PSHUDInViewType_CurrentView);
}];
二、showHandleMessage
显示:[PSProgressHUD showHandleMessageCalculators:^(PSProgressHUD *make) {
make.afterDelay(10).message(@"你好啊");
}];
三、showUploadProgress
使用:MBProgressHUD *hud=[PSProgressHUD showUploadProgressCalculators:^(PSProgressHUD *make) {
make.inViewType(PSHUDInViewType_CurrentView).message(@"我是进度条");
}];
更新进度条:hud.progress=0.5;
消失:
(1)[hud hideAnimated:YES]; (直接使用就可以,前面已经生成MBProgressHUD *hud)
(2)[PSProgressHUD cancelUploadProgressCalculators:^(PSProgressHUD *make) {
make.inViewType(PSHUDInViewType_CurrentView);
}];
*/
@interface PSProgressHUD : NSObject
/**
显示Loading HUD
@param block 配置各种参数
@return MBProgressHUD对象
*/
+ (MBProgressHUD *)showLoadingCalculators:(void (^)(PSProgressHUD * make))block;
/**
消失Loading HUD
@param block 必须配置与showLoading对应的InView
*/
+ (void)cancelLoadingCalculators:(void (^)(PSProgressHUD * make))block;
/**
显示HandleMessage HUD
@param block 配置各种参数
@return MBProgressHUD对象
*/
+ (MBProgressHUD *)showHandleMessageCalculators:(void (^)(PSProgressHUD * make))block;
/**
显示Loading HUD
@param block 配置各种参数
@return MBProgressHUD对象
*/
+ (MBProgressHUD *)showUploadProgressCalculators:(void (^)(PSProgressHUD * make))block;
/**
消失UploadProgress HUD
@param block 必须配置与showUploadProgress对应的InView
*/
+ (void)cancelUploadProgressCalculators:(void (^)(PSProgressHUD * make))block;
#pragma mark - 下面的代码,就是设置保存相应的参数,返回self,
// self=self.message(@"文字"),分两步
// (1)第一步:self.message首先是返回一个block;
// (2)第二步:self=self.messageblock(@"文字") block里面是{ self.msg=@"文字"; 返回self }.
// 对应一般的语法就是:self=[self message:@"文字"];就是这么个意思
/**
.showMessage(@"需要显示的文字")
*/
- (PSProgressHUD *(^)(NSString *))message;
/**
.animated(YES)是否动画,YES动画,NO不动画
*/
- (PSProgressHUD *(^)(BOOL))animated;
/**
.inView(view)
有特殊需要inView的才使用,一般使用.inViewType()
*/
- (PSProgressHUD *(^)(UIView *))inView;
/**
.inViewType(inViewType) 指定的InView
PSHUDInViewType_KeyWindow--KeyWindow,配合MaskType_Clear,就是全部挡住屏幕不能操作了,只能等消失
PSHUDInViewType_CurrentView--当前的ViewController,配合MaskType_Clear,就是view不能操作,但是导航栏能操作(例如返回按钮)。
*/
- (PSProgressHUD *(^)(PSHUDInViewType))inViewType;
/**
.maskType(MaskType) HUD显示是否允许操作背后,
PSHUDMaskType_None:允许
PSHUDMaskType_Clear:不允许
*/
- (PSProgressHUD *(^)(PSHUDMaskType))maskType;
/**
.customView(view),设置customView
注:只对.showMessage(@"")有效
*/
- (PSProgressHUD *(^)(UIView *))customView;
/**
.customView(iconName),带有小图标、信息,
iconName:小图标名字
注:只对.showMessage(@"")有效
*/
- (PSProgressHUD *(^)(NSString *))customIconName;
/**
.afterDelay(2)消失时间,默认是2秒
注:只对.showHandleMessageCalculators有效
*/
- (PSProgressHUD *(^)(NSTimeInterval))afterDelay;
/**
progressType()设置进度条类型
PSProgressType_HorizontalBar--水平进度条
PSProgressType_AnnularBar-----环形进度条
注:只对.showUploadProgressCalculators有效
*/
- (PSProgressHUD *(^)(PSProgressType))progressType;
MBProgressHUD.m
#import "PSProgressHUD.h"
#import "UIApplication+AppRootViewController.h"
@interface PSProgressHUD ()
{
}
//全都可以使用的参数
@property(nonatomic, strong) UIView *ps_inView;/**
现在只是学习一下链式编程的,如果完善封装MBProgressHUD还需要很多各方面的考虑