ReactiveCocoa基礎知識內容2

來源:互聯網
上載者:User

標籤:

引用網路上一些執行個體的代碼,針對ReactiveCocoa的運用可以更加有協助;

 

1:跟AF結合時的寫法,返回RACSignal

- (RACSignal *)fetchQuestionWithTag:(NSString *)tag {        NSString *relativeURL = [NSString stringWithFormat:@"http://api.stackexchange.com/2.1/questions/?site=stackoverflow&order=desc&sort=hot&tagged=%@", tag];    RACSignal *signal =        [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                    AFHTTPRequestOperation *operation = [              [AFHTTPRequestOperationManager manager]              GET:relativeURL              parameters:nil              success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {                                    [subscriber sendNext:responseObject[@"items"]];                  [subscriber sendCompleted];              }              failure:^(AFHTTPRequestOperation *operation, NSError *error){                  [subscriber sendError:error];              }];                        return [RACDisposable disposableWithBlock:^{                [operation cancel];            }];        }];    return signal;    }

 2:RACCommand的運用,作為事件響應

定義一個ViewModel@interface SubscribeViewModel : NSObject@property(nonatomic, strong) RACCommand *subscribeCommand;// write to this property@property(nonatomic, strong) NSString *email;// read from this property@property(nonatomic, strong) NSString *statusMessage;@end
@property(nonatomic, strong) RACSignal *emailValidSignal;實現代碼:- (RACCommand *)subscribeCommand {    if (!_subscribeCommand) {        @weakify(self);        _subscribeCommand = [[RACCommand alloc] initWithEnabled:self.emailValidSignal signalBlock:^RACSignal *(id input) {            @strongify(self);            return [SubscribeViewModel postEmail:self.email];        }];    }    return _subscribeCommand;}+ (RACSignal *)postEmail:(NSString *)email {    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];    manager.requestSerializer = [AFJSONRequestSerializer new];    NSDictionary *body = @{@"email": email ?: @""};    return [[[manager rac_POST:kSubscribeURL parameters:body] logError] replayLazily];}- (RACSignal *)emailValidSignal {    if (!_emailValidSignal) {        _emailValidSignal = [RACObserve(self, email) map:^id(NSString *email) {            return @([email isValidEmail]);        }];    }    return _emailValidSignal;}
調用綁定:- (void)bindWithViewModel {    RAC(self.viewModel, email) = self.emailTextField.rac_textSignal;    self.subscribeButton.rac_command = self.viewModel.subscribeCommand;    RAC(self.statusLabel, text) = RACObserve(self.viewModel, statusMessage);}- (UITextField *)emailTextField {    if (!_emailTextField) {        _emailTextField = [UITextField new];        _emailTextField.borderStyle = UITextBorderStyleRoundedRect;        _emailTextField.font = [UIFont boldSystemFontOfSize:16];        _emailTextField.placeholder = NSLocalizedString(@"Email address", nil);        _emailTextField.keyboardType = UIKeyboardTypeEmailAddress;        _emailTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;    }    return _emailTextField;}- (UIButton *)subscribeButton {    if (!_subscribeButton) {        _subscribeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];        [_subscribeButton setTitle:NSLocalizedString(@"Subscribe", nil) forState:UIControlStateNormal];    }    return _subscribeButton;}- (UILabel *)statusLabel {    if (!_statusLabel) {        _statusLabel = [UILabel new];    }    return _statusLabel;}

說明:RACCommand類用於表示事件的執行,一般來說是在UI上的某些動作來觸發這些事件,比如點擊一個按鈕。RACCommand的執行個體能夠決定是否可以被執行,這個特效能反應在UI上,而且它能確保在其不可用時不會被執行。通常,當一個命令可以執行時,會將它的屬性allowsConcurrentExecution設定為它的預設值:NO,從而確保在這個命令已經正在執行的時候,不會同時再執行新的操作。命令執行的傳回值是一個RACSignal,因此我們能對該傳回值進行next:,completed或error:, 

3:關於RACObserve的用法

監聽對象的成員變數變化,當成員變數值被改變時,觸發做一些事情。 這種情況其實就是IOS KVO機制使用的情境,使用KVO實現,通常有三個步驟:1,給對象的成員變數添加監聽;2,實現監聽回調;3,取消監聽;而通過RAC可以直接實現,RAC的回調是通過block實現的,類似於過程式編程,上下文也更容易理解一些。

a: 情境:當前類有一個成員變數 NSString *input,當它的值被改變時,發送一個請求。

[RACObserve(self, input)      subscribeNext:^(NSString* x){          request(x);//發送一個請求     }]; 

說明:每次input值被修改時,就會調用此block,並且把修改後的值做為參數傳進來。

b:情境:在上面情境中,當使用者輸入的值以2開頭時,才發請求.

[[RACObserve(self, input)       filter:^(NSString* value){           if ([value hasPrefix:@"2"]) {               return YES;           } else {               return NO;           }       }]       subscribeNext:^(NSString* x){          request(x);//發送一個請求      }]; 

c:上面情境是監聽自己的成員變數,如果想監聽UITextField輸入值變化,架構也做了封裝可以代替系統回調

[[self.priceInput.rac_textSignal       filter:^(NSString *str) {           if (str.integerValue > 20) {               return YES;           } else {               return NO;           }       }]       subscribeNext:^(NSString *str) {      request(x);//發送一個請求 }];

d:情境:button監聽 兩個輸入框有值和一個成員變數值,當輸入框有輸入且成員變數為真時,button為可點擊狀態

RAC(self.payButton,enabled) = [RACSignal                                     combineLatest:@[self.priceInput.rac_textSignal,                                                  self.nameInput.rac_textSignal,                                                  RACObserve(self, isConnected)                                                  ]                                     reduce:^(NSString *price, NSString *name, NSNumber *connect){                                     return @(price.length > 0 && name.length > 0 && [connect boolValue]);                                     }];  

說明:同時監聽多個變數變化,當這些變數滿足一定條件時,使button為可點擊狀態

e:情境:滿足上麵條件時,直接發送請求

[[RACSignal                                     combineLatest:@[self.priceInput.rac_textSignal,                                                  self.nameInput.rac_textSignal,                                                  RACObserve(self, isConnected)                                                  ]                                     reduce:^(NSString *price, NSString *name, NSNumber *connect){                                     return @(price.length > 0 && name.length > 0 && ![connect boolValue]);                                     }]                               subscribeNext:^(NSNumber *res){                                   if ([res boolValue]) {                                       NSLog(@"XXXXX send request");                                   }                               }];  

f:distinctUntilChanged直到收到不同值才響應,可以過濾掉那些不必要的網路請求等

    @weakify(self);        //Start Binding our properties    RAC(self.nameField,text) = [RACObserve(self.viewModel, playerName) distinctUntilChanged];        [[self.nameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {        //this creates a reference to self that when used with @weakify(self);        //makes sure self isn‘t retained        @strongify(self);        self.viewModel.playerName = x;    }];

 4:RACScheduler為RAC調度類(主線程,子線程等)

顯示網路下載的圖片

 RAC(self.imageView, image) = [[RACSignal startEagerlyWithScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground] block:^(id <RACSubscriber> subscriber) { NSError *error; NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://ww3.sinaimg.cn/bmiddle/7128be06jw1ei4hfthoj3j20hs0bomyd.jpg"]options:NSDataReadingMappedAlwayserror:&error]; if(error) { [subscriber sendError:error];} else { [subscriber sendNext:[UIImage imageWithData:data]]; [subscriber sendCompleted];} }] deliverOn:[RACScheduler mainThreadScheduler]];

說明:這段代碼會在後台線程立即發起一個請求,然後傳遞到主線程上更新UI,主線程上執行[RACScheduler mainThreadScheduler],訊號傳遞:- (RACSignal *)deliverOn:(RACScheduler *)scheduler

ReactiveCocoa基礎知識內容2

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.