如何使用 objective-c 实现可链接语法?

How to implement chainable syntax with objective-c?

例如:

someObject.a.and.b.offset(5)

在objective-c中,我们知道一个Class可以有属性和方法,如何混合它们来实现可链式语法?如何设计?

看看这个图书馆:Underscore Library

实际上它对 return 您正在操作的同一个对象做了什么,因此您可以对该对象调用更多方法(链接它们)。还使用块属性来获得此语法。

以下是网站上的示例:

NSArray *tweets = Underscore.array(results)
// Let's make sure that we only operate on NSDictionaries, you never
// know with these APIs ;-)
.filter(Underscore.isDictionary)
// Remove all tweets that are in English
.reject(^BOOL (NSDictionary *tweet) {
    return [tweet[@"iso_language_code"] isEqualToString:@"en"];
})
// Create a simple string representation for every tweet
.map(^NSString *(NSDictionary *tweet) {
    NSString *name = tweet[@"from_user_name"];
    NSString *text = tweet[@"text"];

    return [NSString stringWithFormat:@"%@: %@", name, text];
})
.unwrap;

您可能还想看看这个 SO-Thread

显示了另一个实现此行为的库。

这是我的笔记。例如:

@class ClassB;
@interface ClassA : NSObject

//1. we define some the block properties
@property(nonatomic, readonly) ClassA *(^aaa)(BOOL enable);
@property(nonatomic, readonly) ClassA *(^bbb)(NSString* str);
@property(nonatomic, readonly) ClassB *(^ccc)(NSString* str);

@implement ClassA

//2. we implement these blocks, and remember the type of return value, it's important to chain next 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;
    }
}

// Here returns a instance  which is kind of ClassB, then we can chain ClassB's block.
// See below .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;
    }
}

// At last, we can do it like this------------------------------------------
id a = [ClassA new];
a.aaa(YES).bbb(@"HelloWorld!").ccc(@"Objective-C").ddd(NO)