swift成长之路

像swift一样书写OC代码OC链式编程实践

2019-07-04  本文已影响192人  铸造中

链式编程特点 链式编程 = 点语法 事物 串联

同样的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的名字是小明
参数传递过程.png
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地址如下:https://github.com/long-Tan/blogDemo

上一篇 下一篇

猜你喜欢

热点阅读