如何在Objective-C中实现链式语法?

在接触到开源项目 Masonry 后,里面的布局约束的链式写法让我颇感兴趣,就像下面这样:


1

2

3

4

5

6

7

8

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {

    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler

    make.left.equalTo(superview.mas_left).with.offset(padding.left);

    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);

    make.right.equalTo(superview.mas_right).with.offset(-padding.right);

}];

其他语言比如 Lua, 实现链式语法很容易。但在 Objective-C 中,如何实现链式语法呢?

注:这里讨论的链式语法特指的是点链式语法,不同于中括号链式语法,如[[[[someObj method1] method2] method3] method4:someParam]。中括号链式语法相对而言更简单些,每个方法的返回值是下一个方法的发送者即可。

查看 Masonry 源码,起初没看明白,于是搜索了下 Stackoverflow,没有发现类似的问题,便将这个问题发布在了 Stackoverflow 上。这里是地址

总结了下,贴下代码,做个说明。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

@class ClassB;

@interface ClassA : NSObject

// 1. 定义一些 block 属性

@property(nonatomic, readonly) ClassA *(^aaa)(BOOL enable);

@property(nonatomic, readonly) ClassA *(^bbb)(NSString* str);

@property(nonatomic, readonly) ClassB *(^ccc)(NSString* str);

@implement ClassA

// 2. 实现这些 block 方法,block 返回值类型很关键,影响着下一个链式

- (ClassA *(^)(BOOL))aaa

{

    return ^(BOOL enable) {

        //code

        if (enable) {

            NSLog(@"ClassA yes");

        else {

            NSLog(@"ClassA no");

        }

        return self;

    }

}

- (ClassA *(^)(NSString *))bbb

{

    return ^(NSString *str)) {

        //code

        NSLog(@"%@", str);

        return self;

    }

}

// 这里返回了ClassB的一个实例,于是后面就可以继续链式 ClassB 的 block 方法

// 见下面例子 .ccc(@"Objective-C").ddd(NO)

- (ClassB * (^)(NSString *))ccc

{

    return ^(NSString *str) {

        //code

        NSLog(@"%@", str);

        ClassB* b = [[ClassB alloc] initWithString:ccc];

        return b;

    }

}

//------------------------------------------

@interface ClassB : NSObject

@property(nonatomic, readonly) ClassB *(^ddd)(BOOL enable);

- (id)initWithString:(NSString *)str;

@implement ClassB

- (ClassB *(^)(BOOL))ddd

{

    return ^(BOOL enable) {

        //code

        if (enable) {

            NSLog(@"ClassB yes");

        else {

            NSLog(@"ClassB no");

        }

        return self;

    }

}

// 最后我们可以这样做

id a = [ClassA new];

a.aaa(YES).bbb(@"HelloWorld!").ccc(@"Objective-C").ddd(NO)

时间: 2024-08-03 03:12:15

如何在Objective-C中实现链式语法?的相关文章

在python中实现链式调用

用过jquery的一般都知道在jquery中可以链式调用,代码简洁优雅.比如$("a").addClass("test").show().html("foo");. 在redis-py中的pipeline中也可以链式调用,比如pipe.set('foo', 'bar').sadd('faz', 'baz').incr('auto_number').execute() . 那么究竟怎么实现的呢? 很简单,返回对象自己就行了,即return self

java中的链式编程

听到链式编程听陌生的,但是写出来就感觉其实很熟悉 1 package test; 2 3 public class Test { 4 String name; 5 String phone; 6 String mail; 7 String sex; 8 public Test setName(String name) { 9 this.name = name; 10 return this; 11 } 12 public Test setPhone(String phone) { 13 this

ruby中的链式访问和方法嵌套

先看一道题,这道题是codewars上的一道题,我很早就看到了,但是不会写.等到又看到这道题的时候,我刚看完元编程那本书,觉得是可以搞定它的时候了.废话不多说,先看这道题,题目最开始是为JavaScript写的,但是也放在了ruby语言里面,这个没有关系.题目内容是有一个类Calc,通过链式方法调用,可以实现加减乘除.如图给的四个例子.数字只有0-9,运算只有加减乘除,而且每个运算只有一个操作符.(可以先不看下面,自己先想一下怎么写) 首先,每一个例子都是同样的结构---类名和四个方法.拿第一个

jQuery链式语法演示

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head> <meta htt

jquery html标签的链式语法

<div id="ProductNet"> <table border='0' cellspacing='2' cellpadding='0' style='text-align: center; width: 674px;'> <tr> <td class='PNetTD'> 日期类型 </td> <td class='PNetTD'> 更新日期 </td> <td class='PNetTD'

C++中的链式操作

代码编译环境:Windows7 32bits+VS2012. 1.什么是链式操作 链式操作是利用运算符进行的连续运算(操作).它的特点是在一条语句中出现两个或者两个以上相同的操作符,如连续的赋值操作.连续的输入操作.连续的输出操作.连续的相加操作等都是链式操作的样例. 链式操一定涉及到结合律的问题.比如链式操作赋值操作满足右结合律,即a=b=c被解释成a=(b=c).而链式输出操作原则满足左结合律,即cout<<a<<b被解释成(cout<<a)<<b,基本

JAVA中实现链式操作(方法链)的简单例子

使用链式编程带来的简单 student package jetty; import java.util.stream.IntStream; /** * @Auther: Xiao Yu * @Date: Created in 14:52 2018/3/22 */ public class Student { private Integer id; private Integer age; private String name; private String address; private S

Objective - C中属性和点语法的使用

一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 OC中的属性机制提供了便捷的设置和获取实例变量的方式,或者说属性提供了一个默认的设置器和访问器的实现:属性提供的方法是现实可配置的,属性的好处:相当于自己编写这一对方法,属性提供了一系列清晰分明的说明参数来定义设置器和访问器的行为,编译器可以根据你设置的说明参数为你生成相应的方法,减少你的代码量和维护工作量 设置器(sette

通过JavaScript中的链式方法实现JQuery的链式调用

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实现JQuery的链式调用</title> </head> <body> <script> function A(){} A.prototype.v = 2; A.prototype.set = function(num)