Masonry源码阅读笔记——使用Block实现链式编程

导语: 前段时间在阅读Masonry源码时,看到其内部使用了链式编程,比较有趣,这里简单分享一下;

在OC中实现链式编程并不难,最常用的实现是使用Block,具体包括以下几个要点:

1)对于要实现链式编程的函数,使用Block作为其返回值;

2)作为返回值的Block,需在执行后Return自身;

这里看起来似乎不太好理解,下面通过一个例子来说明:

@interface Box : NSObject

- (Box *(^)(CGFloat width))setWidth;
- (Box *(^)(CGFloat height))setHeight;
- (Box *(^)())setProperty;
- (Box *(^)())build;

@end

@implementation Box

- (Box *(^)(CGFloat width))setWidth {
    return ^(CGFloat width){
        NSLog(@"Set width : %f.", width);
        return self;
    };
}

- (Box *(^)(CGFloat height))setHeight {
    return ^(CGFloat height){
        NSLog(@"Set height : %f.", height);
        return self;
    };
}

- (Box *(^)())setProperty {
    return ^{
        NSLog(@"Set other property.");
        return self;
    };
}

- (Box *(^)())build {
    return ^{
        NSLog(@"A box is built.");
        return self;
    };
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Box *box = [Box new];
        box.setWidth(10.f).setHeight(10.f).setProperty().build();
    }
    return 0;
}

 在对象通过点语法调用函数时,返回了一个Block,在执行Block后,又返回了对象本身,这样就能将多个函数调用串联起来,实现链式的效果;

代码执行后为:

当然,链式编程很多时候并没有实际意义,例如上面的Demo,完全可以采用下面的实现:

@interface Box : NSObject

- (Box *)setWidth:(CGFloat)width;
- (Box *)setHeight:(CGFloat)height;
- (Box *)build;

@end

@implementation Box

- (Box *)setWidth:(CGFloat)width {
    NSLog(@"Set width : %f.", width);
    return self;
}

- (Box *)setHeight:(CGFloat)height {
    NSLog(@"Set height : %f.", height);
    return self;
}

- (Box *)build {
    NSLog(@"A box is built.");
    return self;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Box *box = [Box new];
        [[[box setWidth:10.f] setHeight:10.f] build];
    }
    return 0;
}

但这样写一开始还能接受,链条一长时就会出现一堆恶心的中括号,这也是OC一直让人诟病的点;使用Block,形式上会美观许多;

当然,一般情况下还是不推荐链式编程的,因为这么写除了美观外毫无意义(个人愚见);但对于一些特殊的情况,例如使用Bulider模式,这么写可以使代码可读性更好,所以说,具体做法还是要视情况而定;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

c#实现打印功能

2702
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2040
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5406
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

31410
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2526
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3105
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2142
来自专栏杨龙飞前端

scrollto 到指定位置

2494
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5287
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

3859

扫码关注云+社区