链式编程特点 链式编程 = 点语法 事物 串联
同样的hello word代码
swift版
func sayHello(_ name: String) {
NSLog("swift %@ HelloWord", name);
}
self.sayHello("小明");
OC版
-(void)sayHello:(NSString *)name {
NSLog(@"OC %@ hello world",name);
}
[self sayHello:@"小明"];
OC和swift调用函数时候最大的区别就是swift回归了通用写法,利用了点语法传参.而OC则是的最有特点的中括号"[ ]"加冒号的方式来。 那么如何能让OC也想swift一样来实现方法调用呢?
实验
首先我们来做一个实验
@property (nonatomic,copy) NSObject * name; //声明一个属性
{
self.name = @"name"; //调用一个属性
}
这是我们常用的调用属性的用法,这说明我们本身OC还是支持点语法的,他其实会去调用系统根据属性自动生成的setName函数,因此 self.name = setName函数。
再来一个实验:
我单纯写一个sayHello函数,然后通过点语法直接触发
-(void)sayHello {
NSLog(@"sayHello已经触发");
}
{
self.sayHello;
}
//结果如下
2019-07-04 11:36:41.923044+0800 链式编程[2744:55354] sayHello已经触发
可以得出结论,即便不是属性,也能够通过点语法触发的。
1.解决参数传递问题
接下里就要考虑怎么实现 self.sayHello("参数"),通过一个括号传递参数的问题了。OC中我们能通过匿名函数block来把参数写在括号里面,也就是说我们可以通过block的方式把参数带到函数体里面。或者换一种说法,就是把sayHello这个函数返回一个block,我们相当于是在执行一个block。
-(void(^)(NSString * name))sayHello{
void(^block)(NSString* name) = ^(NSString * name) {
NSLog(@"Person的名字是%@",name);
};
return block;
}
执行==
{
self.sayHello(@"小明");
}
执行结果
2019-07-04 14:23:57.880417+0800 链式编程[5207:120317] Person的名字是小明
2.如何连续调用
self.sayHello().helloWorld 要真正变得像链式编程一样可以一直通过"."执行下去,还需要解决一个返回值的问题。 self.sayHello().helloWorld相当于self.sayHello()+self.helloWolrd. 需要解决的就是执行.helloWorld的时候左边的执行者依旧是self就行了。 所以一定要让sayHello返回一个self,才能保证helloWorld的执行.
-(ViewController *(^)(NSString * name))sayHello{
ViewController *(^block)(NSString* name) = ^(NSString * name) {
NSLog(@"Person的名字是%@",name);
return self;
};
return block;
}
-(void)helloWolrd {
NSLog(@"hello world");
}
运行
{
self.sayHello(@"小明").helloWolrd;
}
结果
2019-07-04 14:37:33.327263+0800 链式编程[5383:132370] Person的名字是小明
2019-07-04 14:37:33.327422+0800 链式编程[5383:132370] hello world
只要按这种方式传递self,可以保证一直链下去。
3.更简化得书写
现在可以在调用的时候和swift一样了,可是定义函数一长串的写法还是有些麻烦,接下来我们通过宏定义来优化block。
//name=block名字 obj返回值类型 ...表示任意参数
#define KVAR(name,obj,...) obj(^name)(__VA_ARGS__)
//不带返回值的形式
-(KVAR(,void,NSString *))personNameIs2 {
KVAR(block,void,NSString *) = ^(NSString * name) {
NSLog(@"Person的名字是%@",name);
};
return block;
}
//待返回值的形式 并传递多个参数
-(KVAR(,ViewController *,NSString *,NSString *))MyNameIs1 {
KVAR(block, ViewController *,NSString *,NSString *) = ^(NSString * name1,NSString * name2) {
NSLog(@"我的名字是%@ %@",name1,name2);
return self;
};
return block;
}
执行
{
self.MyNameIs1(@"小明",@" 朋友");
self.personNameIs2(@"小明");
}
执行结果
2019-07-04 15:21:47.254133+0800 链式编程[6231:160293] 我的名字是小明 朋友
2019-07-04 15:21:47.254285+0800 链式编程[6231:160293] Person的名字是小明
需要demo可以加QQ群:839813029