iOS之Objective-C中实现链式语法

链式语法:在一行代码之内多次以点调用的形式调用方法。链式语法能使复杂的代码使用简化,看起来非常的优雅。

Objective-C中一个经典的使用链式语法的例子就是著名的Masonry。https://github.com/SnapKit/Masonry

AutoLayout技术如果不用xib来设置,选择用代码写的话,原生代码写法非常繁琐。例如

[aView addConstraints:@[
    [NSLayoutConstraint constraintWithItem:aView
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:bView
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:0],
    [NSLayoutConstraint constraintWithItem:aView
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:bView
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:2.0]]];

用Masonry提供的链式语法则十分简洁

[aView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(bView.mas_top);
    make.left.equalTo(bView.mas_left).offset(2);
}];

链式语法有两个关键:

  1. 用点调用函数,且可传入参数
  2. 一行语句可以无限调用,无限延伸

要做到第一点,必须使用block;要做到第二点,链式中的每一次调用的返回类型必须支持继续调用下一次。


说的比较抽象,举个栗子~
比如用链式语法扩展NSDictionary的语法

NSDictionary *arr = @{}.append(@"first", @"apple").append(@"second", @"orange").append(@"third", @"red").append(@"forth", @"green");
iOS之Objective-C中实现链式语法_第1张图片
dictionary.png

实现方法

static inline id _dictionaryWithValue(id dictionary, id value, NSString *key) {
    if ([dictionary isKindOfClass:[NSMutableDictionary class]]) {
        [dictionary setValue:value forKey:key];
        return dictionary;
    } else if ([dictionary isKindOfClass:[NSDictionary class]]) {
        NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:dictionary];
        [mutableDic setValue:value forKey:key];
        return mutableDic;
    } else {
        return dictionary;
    }
}

- (NSDictionary *(^)(NSString *, id))append {
    return ^id(NSString *key, id value) {
        return _dictionaryWithValue(self, value, key);
    };
}

需要运用点调用的函数,返回的类型是block,且block有型参,而该block返回的类型是自身的类NSDictionary,于是可以继续调用下一次

这里有个小trick,为了使NSDictionary也支持添加元素,会先转型成NSMutableDictionary。

你可能感兴趣的:(iOS之Objective-C中实现链式语法)