函数式响应编程
ReactiveCocoa的基本使用方法
ReactiveCocoa是github一个开源项目,是在iOS平台上对FRP的实现。FRP的核心是信号,信号在ReactiveCocoa(以下简称RAC)中是通过RACSignal来表示的,信号是数据流,可以被绑定和传递。
可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。
RAC统一了对KVO、UI Event、Network request、Async work的处理,因为它们本质上都是值的变化(Values over time)。
替代KVO
@property (strong) NSString *username; [RACObserve( self ,username) subscribeNext:^( NSString *newName){ NSLog (@ "%@" ,newName); }]; |
只要username发生变化就打印出来。体现绑定和响应。
[[RACObserver( self ,username) filter:^( NSString *newName) { return [newName hasPrefix:@ "j" ]; }] subscribeNext:^( NSString *newName) { NSLog (@ "%@" ,newName); } |
增加一个过滤器
替代selector
1 2 3 4 | self .button.rac_command = [[RACCommand alloc] initWithSignalBlock:^( id _) { NSLog (@ "button was pressed!" ); return [RACSignal empty]; }]; |
流的实现
1 2 3 4 5 | RAC( self , timeLabel.text) = [[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] startWith:[ NSDate date]] map:^ id ( NSDate *value) { NSLog (@ "value:%@" , value); NSDateComponents *dateComponents = [[ NSCalendar currentCalendar] components: NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:value]; return [ NSString stringWithFormat:@ "%02ld:%02ld:%02ld" , ( long )dateComponents.hour, ( long )dateComponents.minute, ( long )dateComponents.second]; }]; |
组合
1 2 3 | RAC( self , submitButton.enabled) = [RACSignal combineLatest:@[ self .usernameField.rac_textSignal, self .passwordField.rac_textSignal] reduce:^ id ( NSString *userName, NSString *password) { return @(userName.length >= 6 && password.length >= 6); }]; |
将usernameField和passwordField的信号绑定在一起做reduce处理。返回一个BOOL值去跟self.submitButton.enabled进绑定。
网络请求
1 2 3 | self .loginCommand = [[RACCommand alloc] initWithSignalBlock:^( id sender) { return [client logIn]; }];<br><br>[ self .loginCommand.executionSignals subscribeNext:^(RACSignal *loginSignal) {<br> [loginSignal subscribeCompleted:^{<br> NSLog (@ "Logged in successfully!" );<br> }];<br>}]; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述