标签: reactive-cocoa

在ReactiveCocoa中链接相关信号

在ReactiveCocoa中,如果我们链接几个相关信号,我们必须使用subscribeNext:链中的下一个信号来接收先前产生的信号的值(例如,异步操作的结果).所以过了一会儿,代码会变成这样的东西(省略了不必要的细节):

RACSignal *buttonClickSignal = [self.logIn rac_signalForControlEvents:UIControlEventTouchUpInside];

[buttonClickSignal subscribeNext:^(UIButton *sender) {    // signal from a button click
    // prepare data

    RACSignal *loginSignal = [self logInWithUsername:username password:password];    // signal from the async network operation

    [loginSignal subscribeNext:^void (NSDictionary *json) {
        // do stuff with data received from the first network interaction, prepare some new data

        RACSignal *playlistFetchSignal = [self fetchPlaylistForToken:token];         // another signal from the async network operation

        [playlistFetchSignal subscribeNext:^(NSDictionary *json) {
            // do more stuff with the returned data
        }]; …
Run Code Online (Sandbox Code Playgroud)

objective-c reactive-programming ios reactive-cocoa

32
推荐指数
1
解决办法
8123
查看次数

ReactiveCocoa的参考所有权语义是什么?

当我创建一个信号并将其带入函数的范围时,其每个Cocoa约定的有效保留计数为0:

RACSignal *signal = [self createSignal];
Run Code Online (Sandbox Code Playgroud)

当我订阅信号时,它会保留订阅者并返回一个一次性的,根据Cocoa约定,它也有一个保留计数为零.

RACDisposable *disposable = [signal subscribeCompleted:^ {
    doSomethingPossiblyInvolving(self);
}];
Run Code Online (Sandbox Code Playgroud)

大多数情况下,订户将关闭并引用self其ivars或封闭范围的其他部分.因此,当您订阅信号时,信号具有对订户的拥有参考,并且订户具有您自己的参考.你得到的一次性用品有一个信号的拥有参考.

disposable -> signal -> subscriber -> calling scope
Run Code Online (Sandbox Code Playgroud)

假设您持有该一次性用品,以便您可以在某个时间点取消订阅(例如,如果信号是从Web服务检索数据并且用户导航离开屏幕,则取消她查看正在检索的数据的意图).

self.disposeToCancelWebRequest = disposable;
Run Code Online (Sandbox Code Playgroud)

此时我们有一个循环参考:

calling scope -> disposable -> signal -> subscriber -> calling scope
Run Code Online (Sandbox Code Playgroud)

负责任的事情是确保在取消请求或请求完成后循环中断.

 [self.disposeToCancelWebRequest dispose]
 self.disposeToCancelWebRequest = nil;
Run Code Online (Sandbox Code Playgroud)

请注意,self在释放时不能执行此操作,因为保留周期永远不会发生这种情况!在回调用户期间,在打破保留周期方面看起来似乎有些可疑,因为信号可能在其实现仍然在调用堆栈上时被释放.

我还注意到实现保留了一个进程全局活动信号列表(截至我最初提出这个问题时).

使用RAC时如何考虑所有权?

cocoa reactive-programming reactive-cocoa

28
推荐指数
1
解决办法
4261
查看次数

具有ReactiveCocoa的iOS应用程序的ViewModel模式

我正在努力将RAC集成到我的项目中,目标是创建一个ViewModel层,允许从网络轻松缓存/预取(以及MVVM的所有其他好处).我对MVVM或FRP还不是特别熟悉,我正在尝试为iOS开发开发一个漂亮的,可重用的模式.我有几个问题.

首先,这就是我将ViewModel添加到我的一个视图中的方式,只是为了尝试一下.(我希望这里稍后参考).

在ViewController viewDidLoad中:

@weakify(self)

//Setup signals
RAC(self.navigationItem.title) = self.viewModel.nameSignal;
RAC(self.specialtyLabel.text) = self.viewModel.specialtySignal;
RAC(self.bioButton.hidden) = self.viewModel.hiddenBioSignal;
RAC(self.bioTextView.text) = self.viewModel.bioSignal;

RAC(self.profileImageView.hidden) = self.viewModel.hiddenProfileImageSignal;    

[self.profileImageView rac_liftSelector:@selector(setImageWithContentsOfURL:placeholderImage:) withObjectsFromArray:@[self.viewModel.profileImageSignal, [RACTupleNil tupleNil]]];

[self.viewModel.hasOfficesSignal subscribeNext:^(NSArray *offices) {
    self.callActionSheet = [[UIActionSheet alloc] initWithTitle:@"Choose Office" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
    self.directionsActionSheet = [[UIActionSheet alloc] initWithTitle:@"Choose Office" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
    self.callActionSheet.delegate = self;
    self.directionsActionSheet.delegate = self;
}];

[self.viewModel.officesSignal subscribeNext:^(NSArray *offices){
    @strongify(self)
    for (LMOffice *office in offices) {
        [self.callActionSheet addButtonWithTitle: office.name ? office.name : office.address1];
        [self.directionsActionSheet addButtonWithTitle: office.name ? office.name …
Run Code Online (Sandbox Code Playgroud)

mvvm ios reactive-cocoa

28
推荐指数
1
解决办法
6843
查看次数

为什么RACCommand的块返回信号?

我一直在学习很多关于ReactiveCocoa的知识,但还有一件事让我感到困惑:为什么信号块会自动RACCommand返回信号?

我理解RACCommand它的canExecute信号和信号块的用例,以及如何将它连接到UI元素.但是,返回其他东西会有什么情况[RACSignal empty]呢?

infoButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    // Do stuff

    return [RACSignal empty];
}];
Run Code Online (Sandbox Code Playgroud)

objective-c reactive-programming ios reactive-cocoa

26
推荐指数
3
解决办法
4988
查看次数

如何在进行API调用之前使用ReactiveCocoa进行透明身份验证?

我在一个应用程序中使用ReactiveCocoa,该应用程序调用远程Web API.但在从给定的API主机检索任何内容之前,应用程序必须提供用户的凭据并检索API令牌,然后用于签署后续请求.

我想抽象出这个身份验证过程,以便每当我进行API调用时它都会自动发生.假设我有一个包含用户凭据的API客户端类.

// getThing returns RACSignal yielding the data returned by GET /thing.
// if the apiClient instance doesn't already have a token, it must
// retrieve one before calling GET /thing 
RAC(self.thing) = [apiClient getThing]; 
Run Code Online (Sandbox Code Playgroud)

如何使用ReactiveCocoa透明地导致API的第一个(也是唯一的)请求检索,并且作为副作用,在发出任何后续请求之前安全地存储API令牌?

我还可以使用combineLatest:(或类似的)启动多个同时发出的请求,并且它们都会隐式等待检索令牌.

RAC(self.tupleOfThisAndThat) = [RACSignal combineLatest:@[ [apiClient getThis], [apiClient getThat]]];
Run Code Online (Sandbox Code Playgroud)

此外,如果在进行API调用时检索令牌请求已经在飞行中,则该API调用必须等到检索令牌请求完成.

我的部分解决方案是:

基本模式将用于将flattenMap:产生令牌的信号映射到给定令牌执行所需请求并产生API调用结果的信号.

假设一些方便的扩展NSURLRequest:

- (RACSignal *)requestSignalWithURLRequest:(NSURLRequest *)urlRequest {
    if ([urlRequest isSignedWithAToken])
        return [self performURLRequest:urlRequest];

    return [[self getToken] flattenMap:^ RACSignal * (id token) {
        NSURLRequest *signedRequest = …
Run Code Online (Sandbox Code Playgroud)

cocoa reactive-programming reactive-cocoa

25
推荐指数
1
解决办法
5021
查看次数

有没有人基于RACSignal自我更新可变表视图?

现在已经完全支持KVO了,是否有人制作了一个可变的表视图,它将RACSignal作为其dataSource?理想情况下,不需要任何配置.

RACSignal *commentsSignal;
UITableView *table = [UITableView new];
table.dataSourceSignal = commentsSignal;
[self.view addSubview:table];
// No more basic config
Run Code Online (Sandbox Code Playgroud)

objective-c ios reactive-cocoa racsignal

23
推荐指数
1
解决办法
1309
查看次数

Reactive Cocoa中RACAble(),RACObserve()和RACBind()之间的区别

我是Reactive Programming的新手.我已经通过无可可的文档了,但无法实现之间的差异RACAble(),RACObserve()RACBind().

请帮助我,通过一些示例代码片段来理解方面.

我认为它RACAble()被替换RACObserve()为一些选项/参数.如果我不对,请在这方面纠正我.

RACObserve() skip:相似的RACAble()

objective-c reactive-programming reactive-cocoa

23
推荐指数
1
解决办法
4211
查看次数

catch:和subscribeError之间的区别:

ReactiveCocoa中,subscribeError:方法与catch:?之间的区别是什么?你为什么要回信号catch:

reactive-programming reactive-cocoa

22
推荐指数
1
解决办法
2291
查看次数

解释ReactiveCocoa/libextobjc中的弱化和强化工作方式

我知道你应该使用@weakify @strongify来避免保留周期,但我不完全理解它们是如何实现这一目的的?

reactive-cocoa libextobjc

22
推荐指数
2
解决办法
8013
查看次数

Objective-C self - > _ ivar access with explicit vs implicit self->

一般问题

直到现在,我一直认为self->_ivar相当于_ivar.今天我发现这并不完全正确.

例如,请参阅以下代码段:

@interface TestClass : NSObject {
    NSString *_testIVar;
}
@end

@implementation TestClass

- (instancetype)init
{
    if ((self = [super init])) {
        _testIVar = @"Testing Only";
    }
    return self;
}

- (void)test
{
    {
        NSInteger self = 42;
        NSLog(@"without arrow: %@", _testIVar);        /* OK              */
        NSLog(@"with    arrow: %@", self->_testIVar);  /* COMPILER ERROR! */
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

即使我隐藏了原始self的一些NSInteger也命名self,隐含的ivar语法_testIVar仍然找到"原始"自我,而self->_testIVar显然不是.在后一种情况下,编译器正确地抱怨

成员引用类型'NSInteger'(又名'long')不是指针

然而,在第一种情况下,它只是起作用.

现实世界的问题

这个例子似乎相当人为,但根本不是.例如,ExtObjC项目(由ReactiveCocoa使用)通过定义一个非常方便的语法(不需要编写奇怪和繁琐的写入)来定义非常方便 …

block objective-c ivar reactive-cocoa

20
推荐指数
1
解决办法
2458
查看次数