zoukankan      html  css  js  c++  java
  • 如何在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)
  • 相关阅读:
    学期总结
    C语言I博客作业09
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言博客作业04
    C语言I博客作业03
    C语言I博客作业02
    C语言I博客作业01
    学期总结
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4998778.html
Copyright © 2011-2022 走看看