Object-C 关于「链式编程」与「函数式编程」简单实践

本文介绍Objective-C中实现函数式编程与链式编程的方法,通过block闭包特性实现函数的返回与链接调用,提供了具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

「函数式编程」:每个函数都有返回,函数作为第一类对象
「链式编程」:函数返回的对象继续进行函数,组成一串长链(函数式编程的体现?)

  • 拿 jQuery 简单举个例子
    var text = $('#content').children().eq(1).children().eq(0).text();
  • 对比 Object-C,
    // 执行方法,而不是函数,没有返回,虽然参数部分有返回,但是毕竟是面向对象
   [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];

    // 就算使用返回 self,写链式也很难受
    [[[person eat] run] eat];

OC 实现「函数编程」与「链式编程」

  • . 语法使用,是对象属性
  • 使属性拥有参数,需要 block 函数闭包作为属性
// 定义 block
typedef Person* (^eatBlock)(NSString *name);
// block 作为属性
@property (nonatomic, copy) eatBlock eat;
// block 的 getter 方法,本身是函数,可以引入参数,而函数又返回 self,得以继续
- (eatBlock)eat {
    return ^Person* (NSString *a) {
        NSLog(@"吃了:%@",a);
        return self;
    };
}


Person *person = [[Person alloc] init];
person.eat(@"苹果").eat(@"橘子").eat(@"香蕉");

抛开实例,只关注函数结果

  • 可以把实例本身封装起来
    NSString *resMessage = [Person makeMessage:^(Person *person) {
        person.eat(@"橘子").run(12).pause.eat(@"苹果");
    }];
  • 部分代码
@implementation Person


- (NSMutableArray *)infoList {
    if (!_infoList) {
        _infoList = [NSMutableArray array];
    }
    return _infoList;
}


+ (NSString *)makeMessage:(void(^)(Person *person))block {
    if (block) {
        Person *person = [[Person alloc] init];
        block(person);
        return [person.infoList componentsJoinedByString:@","];
    }
    return nil;
}


- (eatBlock)eat {
    return ^Person* (NSString *a) {
        NSLog(@"吃了:%@",a);
        [self.infoList addObject:[NSString stringWithFormat:@"吃了 %@", a]];
        return self;
    };
}


- (runBlock)run {
    return ^Person *(NSInteger step) {
        NSLog(@"走了:%zi 步", step);
        [self.infoList addObject:[NSString stringWithFormat:@"走了 %zi 步", step]];
        return self;
    };
}


- (Person *)pause {
    NSLog(@"休息一下");
    [self.infoList addObject:@"休息以下"];
    return self;
}
@end

Demo 地址


block 回顾

内部 block
// 定义方法
- (NSInteger)sumWithA:(NSInteger)a b:(NSInteger)b {
    return a + b;
}


// 定义 block
NSInteger (^sum)(NSInteger, NSInteger) = ^(NSInteger a, NSInteger b) {
    return a + b;
};




NSInteger res1 = [self sumWithA:1 b:2];
NSInteger res2 = sum(1, 2);
实例 block
@property (nonatomic, copy) NSInteger(^block)(NSInteger a, NSInteger b);


self.block = ^(NSInteger a, NSInteger b) {
    return a + b;
};    


NSInteger res = self.block(1, 2);

block 的 getter 与 setter

typedef NSInteger(^typeOfBlock)(NSInteger a, NSInteger b);
@property (nonatomic, copy) typeOfBlock typeBlock;
getter
  • 实际获取了 block 函数本身,可以当成函数使用(向里传参)
- (typeOfBlock)typeBlock {
    return ^NSInteger(NSInteger a, NSInteger b) {
        return a + b;// 此处是 block 函数执行体
    };
}


NSInteger res4 = self.typeBlock(2, 3);
setter(正常实例)
  • 给实例指定 block 函数(与实例一样的 get 和 set)
  • 这个应该不怎么用吧,仅仅把函数执行体,放到外面而已
- (void)setTypeBlock:(typeOfBlock)typeBlock {
    if (!_typeBlock) {
        _typeBlock = typeBlock;
    }
}


[self setTypeBlock:^NSInteger(NSInteger a, NSInteger b) {
    return a + b;// 此处是 block 函数执行体
}];
setter 2(内部调用)
  • 内部使用了 block,即可反向传参,因为执行体在外面(向外传参)
  • 这个很多时候用来代替了 delegate 传参的方式
- (void)setTypeBlock:(typeOfBlock)typeBlock {
    if (typeBlock) {
        NSInteger res = typeBlock(2, 3);// 实际就是执行了 block 函数一次,但作用可以反向传参
        NSLog(@"这里是 res:%zi", res);
    }
}


[self setTypeBlock:^NSInteger(NSInteger a, NSInteger b) {
    NSLog(@"%zi,%zi", a, b);
    return a + b;// 此处是 block 函数执行体
}];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值