Block的链式编程

原创 2015年07月11日 00:03:44

今天讲点iOS开发中如何妙用Block的链式编程来让代码更加清爽。

       

一.在iOS开发中,不带参数的方法是可以通过点语法来调用的。

示例代码:

/** 声明person类 */

@interface Person : NSObject

- (void)study;

@end

/** 实现person类 */

@implementation Person

- (void)study

{

    NSLog(@"学习");

}

@end


/** 调用person类 */

int main(int argc,const char * argv[]) {

    @autoreleasepool {

        Person *p = [[Personalloc] init];

        p.study;  // 这里编译器会报警告,因为你的study并没有返回值,编译器不建议如此调用方法

    }

    return0;

}


二.程序中的地址

我们知道一个指针代表这一个地址,通过这个地址,我们可以对地址里的信息进行访问

其实函数,block,所有非指针数据类型也都是有地址的。而它们的函数名,变量名在底层处理中会变为函数与变量的地址,从而实现了对函数的调用,对变量的访问。

我定义一个函数

void test ()

{

        printf("测试");

}

其实“test”就代表着这段代码的地址


我定义一个block

void (^myBlock)() = ^(){

      NSLog(@"我的block");

};

我们用runtime去rewrite这个block时会发现,在底层中,block会被变为一段函数,并且block中拥有isa指针,这以为着block其实也是一种对象或者结构体(有点跑题了...)


总而言之,我们可以很愚昧的把函数名,block名看做那段源码的地址,从而达到对那段源码的访问。


说了这么多,你可能会想这跟我们今天的主题有什么关系呢?哈哈,原谅我卖这么多关子,这些都是印子,有助于我们理解Block的链式编程。

好了,废话不多说,进入我们今天的主题--如何用block实现链式编程!


三.用Block实现链式编程

首先我先把实现代码写出来

如下:

/** 类的声明 */

@interface Person : NSObject

- (Person *(^)())eat;

- (Person *(^)())sleep;

@end


/** 类的实现 */

@implementation Person

- (Person *(^)())eat

{

    return ^(){

        NSLog(@"吃饭");

        returnself;

    };

}

- (Person *(^)())sleep

{

    return ^(){

        NSLog(@"睡觉");

        returnself;

    };

}

@end


/** 调用 */

int main(int argc,const char * argv[]) {

    @autoreleasepool {

        Person *p = [[Personalloc] init];

        p.eat().sleep().eat().sleep();             //  在这里我们就可以优雅的使用Block的链式编程,怎么样有木有感觉很清爽?

    }

    return0;

}


看了上面的代码,你可能觉得蒙蒙的,没关系我们来一步一步分析它是如何实现的


首先我们看eat方法与sleep方法的声明,我们声明了这两个方法,因为无参,所以我们可以通过点语法直接调用。这两个方法都要求返回一个Person *(^)()类型的block

其次我们看eat方法与sleep方法的实现,我们老老实实的返回了一个Person *(^)()类型的block,OK语法是没有问题的!

最后我们看main函数里的调用 p.eat()  首先我们通过点语法调用了eat方法,这个eat方法返回了一个Person *(^)()类型的block的内存地址,紧接着就是(),我们拿着返回的block给它带了个(),这就调用了我们返回的block,这个block执行完毕后又返回了Person类型的指针,于是我们又可以开开心心的去调用Person的实例方法!这样我们就达到了链式编程的目的。


四.升级版,如何带参!

这里我们讨论,如何能给刚刚的eat和sleep方法带上参数!毕竟没有参数的方法过分局限。

同样,我还是先贴上代码:

/** 声明 */

@interface Person : NSObject

- (Person *(^)(NSString *))eat;

- (Person *(^)(NSString *))sleep;

@end


/** 实现 */

@implementation Person

- (Person *(^)(NSString *))eat

{

    return ^(NSString *foodName){

        NSLog(@"%@", foodName);

        returnself;

    };

}

- (Person *(^)(NSString *))sleep

{

    return ^(NSString *who){

        NSLog(@"%@", who);

        returnself;

    };

}

@end


/** 调用 */

int main(int argc,const char * argv[]) {

    @autoreleasepool {

        Person *p = [[Personalloc] init];

        p.eat(@"大便味的咖喱").sleep(@"最漂亮的女人");   // 有木有一种oc,java傻傻分不清楚的感觉~~

    }

    return0;

}


首先你可能会想,给方法带参不就是eat:(NSString *)foodName嘛,但是这样是不行的,因为oc的语法限制,带上了参数我们便不能通过点语法去调用方法了。

所以我们必须换一种思路,这种思路就是:通过block的参数来给方法传参。


先看声明部分,eat与sleep都要求我们返回一个Person *(^)(NSString *)类型的block,我们再看这个block的类型,一种返回Person指针且传NSString *的block。

我们再看声明部分,我们在方法内的的确确的返回了一个Person *(^)(NSString *)类型的block,OK,语法还是正确的。

最后我们看调用,首先p.eat返回了一个Person *(^)(NSString *)类型的block的block,这个block后面就是一个(),并且这个()内部有一个参数,这不正是调用这个block的正确格式嘛!!!block执行完毕后,又返回了Person 类型的指针,于是乎我们又可以开开心心的调用Person的实例方法了。就这样我们借助了block的参数,达到了给方法传参的目的!


五.结尾总结

Block的链式编程其实就是借助了c语言的语法特性,通过函数的返回值与手写(),从而达到了调用block的目的。

希望大家可以借鉴这个知识点来让自己的code变得更加清爽。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

objc利用block实现链式编程方法

objc利用block实现链式编程方法        因为不好读。block和其他语言的匿名函数一样,很多程序员刚开始很难主动去用他。     本文描述block作为属性的实际使用,看懂block...

block的函数式编程和链式编程

一 block的函数式编程和链式编程定义及实例1.定义函数式编程:它属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。代表:ReactiveCocoa。链式编程:是将多个操作...

Block (三) OC中的函数式编程\链式编程

简单介绍OC 中 链式编程/函数式编程 的核心思想和实现技巧。with block

block的高级用法(二) -- block作为返回值,链式编程思想

相信用过Masonry框架的同学,估计都对里面的调用方式记忆犹新 -- 都是用点语法调用的。 他是怎么做到的能这样一直调用呢?大家可以思考下,在iOS中,一个函数的返回值还能添加参数的, 会是什么实现...

【步兵 经验篇】 链式编程

【步兵 经验篇】 链式编码 by EOS.什么是链式编程链式编程就是以函数返回this的方式把多个语句串联起来。 上面也提到了一点,那就是更贴近人的思维逻辑,思维连贯、语意集中。 这样思路就会变的清...

接口和链式编程

  • 2013-11-06 17:02
  • 253KB
  • 下载

浅谈链式编程

  • 2016-09-02 11:09
  • 1.85MB
  • 下载

简单模拟JQ链式编程核心

简单模拟JQ链式编程核心
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)