Download - ReactiveCocoa Goodness - Part I of II
![Page 1: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/1.jpg)
REACTIVECOCOA GOODNESSPART I OF II
![Page 2: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/2.jpg)
3PHASES OF LEARNING REACTIVECOCOA
![Page 3: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/3.jpg)
1
![Page 4: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/4.jpg)
![Page 5: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/5.jpg)
2
![Page 6: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/6.jpg)
![Page 7: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/7.jpg)
3
![Page 8: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/8.jpg)
![Page 9: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/9.jpg)
WHAT IS REACTIVECOCOA?
![Page 10: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/10.jpg)
AUTHORS (GITHUB FOLKS) SAY:ReactiveCocoa (RAC) is an Objective-C framework inspired by Functional Reactive Programming. It provides APIs for composing and transforming
streams of values.
![Page 11: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/11.jpg)
THE IDEA TO CREATE REACTIVECOCOA SEEMS TO HAVE COME FROM RX (MICROSOFT .NET),
WHICH IS SIMILAR.
![Page 12: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/12.jpg)
RAC ALLOWS US AN EVENT-BASED PROGRAMMING MODEL WHICH MAKES STATE
TRACKING OBSOLETE - in theory.
![Page 13: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/13.jpg)
ONE THING IS CERTAIN:IT MAKES STATE EASIER TO MAINTAIN.
![Page 14: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/14.jpg)
SOME PEOPLE THINK RAC IS ALL ABOUT THIS... // Keeps someObject.property synced with // otherObject.other.property // -> one-way binding RAC(someObject, property) = RACObserve(otherObject, other.property);
![Page 15: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/15.jpg)
...OR THIS... // Keeps someObject.property synced with // otherObject.other.property // and vice versa -> two-way binding RACChannelTo(someObject, property) = RACChannelTo(otherObject, other.property);
![Page 16: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/16.jpg)
... BUT RAC IS SO MUCH MORE!
![Page 17: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/17.jpg)
RAC = SIGNALS + SUBSCRIBERS
![Page 18: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/18.jpg)
A SIGNAL IS A STREAM OF VALUES.SIGNALS CAN BE TRANSFORMED, COMBINED, ETC.
![Page 19: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/19.jpg)
A SUBSCRIBER SUBSCRIBES TO A SIGNAL.RAC LETS BLOCKS, OBJECTS, AND PROPERTIES SUBSCRIBE TO SIGNALS.
![Page 20: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/20.jpg)
USING SIGNALS AND SUBSCRIBERS, YOU CAN MODEL ANY REACTION TO ANY EVENT THAT
HAPPENS IN YOUR APPLICATION.
![Page 21: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/21.jpg)
MOST OF UI-CENTERED CODEACTUALLY REACTS TO SOMETHING!
![Page 22: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/22.jpg)
DIVING INTO SIGNALS
![Page 23: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/23.jpg)
MOST TRIVIAL SIGNAL:RACEmptySignal
// Sends no value. Ever. #yolo RACSignal *sendNothing = [RACEmptySignal empty];
![Page 24: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/24.jpg)
MOST TRIVIAL SIGNAL THAT SENDS VALUES:RACReturnSignal
// All subscribers will immediately receive an // empty array as 'next' value on subscription. RACSignal *returnEmptyArrayOnSubscription = [RACReturnSignal return:@[]];
![Page 25: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/25.jpg)
BRIDGE OOP/FRP WORLD:RACSubject
- (id)init { if (self = [super init]) { self.loadMoreSubject = [RACSubject subject]; }
return self; }
- (void)loadMore { [self.loadMoreSubject sendNext:nil]; }
![Page 26: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/26.jpg)
OTHER SIGNALS:RACSignal (DUH!),
RACReplaySubject, RACChannelTerminal, RACErrorSignal,...
![Page 27: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/27.jpg)
UIKIT BATTERIES INCLUDED: UITextfield.rac_textSignal NSObject.rac_willDeallocSignal UITableviewCell.rac_prepareForReuseSignal UIButton.rac_command UIRefreshControl.rac_command ...
![Page 28: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/28.jpg)
SIGNAL LIBRARIES ON COCOAPODSpod search RACExtensionspod search reactivecocoa
![Page 29: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/29.jpg)
YOU BUILD APP LOGIC BY TRANSFORMING VALUES SENT
BY SIGNALS
![Page 30: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/30.jpg)
MAP [usersSignal map:^NSString *(MMUser *user) { return user.email; }];
![Page 31: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/31.jpg)
FILTER [usersSignal filter:^BOOL(MMUser *user) { return user.isEnabled; }];
![Page 32: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/32.jpg)
ZIP // If signalOne and signalTwo have both // sent a value, signalOne's value is passed on. [RACSignal zip:@[signalOne, signalTwo] reduce:^id(RACTuple *t) { return t.first; }];
![Page 33: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/33.jpg)
MERGE SIGNALS // No matter if the user or a notification // provokes a value send, the value is passed // on in both cases. [RACSignal merge:@[userTriggerSignal, notificationCenterTriggerSignal]]
![Page 34: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/34.jpg)
FLATTEN OR MAP/FLATTEN SIGNALS // First maps all freshly sent requestParams to a new // signal that will eventually send a server response. // Then applies flatten such that we get all those // server responses directly as values. RACSignal *currentUsers = [requestParamsSignal flattenMap:^RACStream *(NSDictionary *requestParams) { return [MMAPI.sharedInstance allUsersWithParams:requestParams]; } ];
![Page 35: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/35.jpg)
(YEAH, YOU CAN BUILDSIGNALS OF SIGNALS OF
SIGNALS.)
![Page 36: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/36.jpg)
![Page 37: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/37.jpg)
CONCAT SIGNALS // Catches any error in signal, waits 1 second, // then passes on the error, and then immediately // retries (= resubscribes). Forever. [[signal catch:^(NSError *error) { return [[[RACSignal empty] delay:1.0] concat:[RACSignal error:error]]; }] retry];
![Page 38: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/38.jpg)
SCAN/REDUCE // Starts off with a mutable array, and adds all // events that are ever sent by the 'events' signal. // E.g. for infinite scrolling. RACSignal *combinedEventsInAllPages = [events scanWithStart:NSMutableArray.new reduce:^id(NSMutableArray *running, NSArray *eventsInPage) { [running addObject:eventsInPage]; return running; }];
![Page 39: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/39.jpg)
SKIP VALUES // RACObserve immediately sends the current // property value. Skip:1 'swallows' that one. [[RACObserve(self, someProperty)] skip: 1];
![Page 40: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/40.jpg)
TAKE X VALUES AND STOP // Only sends the first 3 text values. // Then the signal is disposed of. [textField.rac_textSignal take: 3];
![Page 41: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/41.jpg)
DISTINCT UNTIL CHANGED// Does only send distinct (= first and new) values.[RACObserve(self, isUserLoggedIn) distinctUntilChanged];
![Page 42: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/42.jpg)
THROTTLE/DELAY/REPEAT...... THERE IS A TRANSFORM FOR EVERYTHING.
![Page 43: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/43.jpg)
SIGNALS CAN SWITCH THREADS RAC(self, results) = [[[[RACReturnSignal return:@[@(M_PI), @(M_E), @(M_SQRT1_2)]] deliverOn:RACScheduler.scheduler] // All that follows happens on a background thread map:^NSNumber *(NSNumber *specialNumber) { // Do expensive calculations // NSNumber *result = ... return result; }] // All that follows (RAC assignment) happens // on the main thread deliverOn:RACScheduler.mainThreadScheduler];
![Page 44: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/44.jpg)
RACCOMMAND = ONE-OFF SIGNAL WRAPPER self.registerCommand = [[RACCommand alloc] initWithEnabled: [self.emailField.rac_textSignal map:^id(NSString *text) { return @(text.length > 0); }] signalBlock:^RACSignal *(NSDictionary *params) { return [MMAPI.sharedInstance registerWithParams:params]; }];
[self.registerCommand.executionSignals.flatten subscribeNext:^(id result) { NSLog(@"Successfully registered!"); }];
// ...
[self.registerCommand execute:@{MMAPIRegisterEmail: self.emailField.text, MMAPIRegisterPassword: self.pwField.text}];
![Page 45: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/45.jpg)
SIGNALS CAN BE HOT OR COLD
A hot signal is a signal that sends values (and presumably does work) regardless of whether it
has any subscribers.
A cold signal is a signal that defers its work and the sending of any values until it has a
subscriber.
Hot signals often don't send subscribers all values of all time, but only values after their
subscription time.
![Page 46: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/46.jpg)
SO WE HAVE SIGNALS.NOW WE NEED TO SUBSCRIBE.
![Page 47: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/47.jpg)
SUBSCRIBE WITH A BLOCK // Prints current date & time every second RACSignal *dates = [RACSignal interval:1.0 onScheduler:RACScheduler.mainThreadScheduler]; [dates subscribeNext:^(NSDate *date) { NSLog([NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle]); }];
![Page 48: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/48.jpg)
SUBSCRIBE WITH A PROPERTY (KEYPATH) // RAC() is a clever macro that abuses // subscripting to let subscription look // like a left-hand assignment RAC(self.proxyObject.awesomeArray) = [RACReturnSignal return:@[]];
![Page 49: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/49.jpg)
INJECT BLOCK-BASED SIDE-EFFECTS // doNext: is 'woven' into the signal chain, // the side-effect becomes part of the signal. // Dangerous, but sometimes necessary! parametersOnRefreshOrParameterChanged = [parametersOnRefreshOrParameterChanged doNext:^(NSDictionary *parameters) { @strongify(self) self.isRefreshing = YES; }];
![Page 50: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/50.jpg)
SUBSCRIBE WITH A METHOD // Calls updateAuthorizationWithAuthToken: when // RACObserve() sends a value. RACObserve() // will btw immediately send the first value, // synchronously. [self rac_liftSelector: @selector(updateAuthorizationWithAuthToken:) withSignals: RACObserve(MMSession.sharedSession, currentCredentials.authToken), nil];
![Page 51: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/51.jpg)
WHAT RAC BUYS YOU
![Page 52: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/52.jpg)
CAN BIND UI COMPONENT VALUES TO MODEL VALUES, INCLUDING TRANSFORMATIONS ...
![Page 53: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/53.jpg)
... WHICH LEADS TO:A REAL MVVM PARADIGM
![Page 54: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/54.jpg)
CAN CALL METHODS WITH MULTIPLE PARAMETERS WHEN SIGNALS FIRE IN A
CERTAIN CONFIGURATION
![Page 55: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/55.jpg)
ELIMINATES THOSE ERROR-PRONE BOOL FLAGS YOU USE TO KEEP TRACK OF COMPLEX
STATE
![Page 56: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/56.jpg)
CAN WAIT FOR MULTIPLE SIGNALS UNTIL IT DOES SOMETHING
(TEDIOUS AND DANGEROUS TO DO WITH BOOL FLAGS)
![Page 57: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/57.jpg)
MAKES THREAD SWITCHES EASY AS !
![Page 58: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/58.jpg)
FORCES YOU TO THINK TWICE BEFORE INTRODUCING A SIDE-EFFECT.
![Page 59: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/59.jpg)
ENCOURAGES IMMUTABLE OBJECTS(BUT DOES NOT ENFORCE THEM).
![Page 60: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/60.jpg)
MAKES CODE EVEN MORE REUSABLE(E.G.NETWORK RESPONSE ERROR FILTER)
![Page 61: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/61.jpg)
NICE INTERFACE TO KVO AND NSNotificationCenter
![Page 62: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/62.jpg)
HAS NICE COLLECTION UTILS INDEPENDENT OF SIGNALS
(MIGHT GET REMOVED SOMEDAY):RACSequence
![Page 63: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/63.jpg)
LIMITATIONS & PITFALLS
![Page 64: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/64.jpg)
BLOCKS CAN EASILY CREATE RETAIN CYCLES☞ ALWAYS USE @WEAKIFY AND @STRONGIFY
![Page 65: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/65.jpg)
IF YOU OVERDO IT, PERFORMANCE SUFFERS☞ WATCH BINDINGS IN UITABLEVIEWCELLS!
![Page 66: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/66.jpg)
NO WAY FOR DISTINCTUNTILCHANGED TO NOT USE ISEQUAL !
![Page 67: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/67.jpg)
NO SPECIAL TREATMENT FOR MUTABLE ARRAYS
![Page 68: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/68.jpg)
[[[[[[[[CODE BECOMES] HARD] TO] UNDERSTAND] IF YOU] NEST] SIGNALS]
TOO MUCH]☞ USE INTERMEDIATE PROPERTIES!
![Page 69: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/69.jpg)
HOW DOES RACDO ALL THIS?
![Page 70: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/70.jpg)
BLOCKS, KVO,METHOD SWIZZLING,
MACROS, GCD, LOCKS,...(maybe every runtime feature there is)
![Page 71: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/71.jpg)
MEMORY MANAGEMENT just works™.BUT IT'S EASY TO CREATE SIGNALS THAT
LIVE FOREVER!
![Page 72: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/72.jpg)
RAC'S CODE IS REALLY ADVANCED STUFF, BUT HAVING A LOOK AT IT IS WORTH IT.
![Page 73: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/73.jpg)
A WORD ABOUT SWIFT:RAC can be used with Swift (didn't test it yet),
but a pure Swift implementation will take a while.Also, KVO will not work without NSObject anyway.
Proof of concept is currently being merged into RAC:https://github.com/jspahrsummers/RxSwift
![Page 74: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/74.jpg)
IF YOU WANT TO LEARN RAC:1. First have a look at how subscriptions work
2. Read through RAC's Github issues (mostly RAC Q/A)3. Start slow, create a lot of intermediate properties
4. Go wild!
![Page 75: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/75.jpg)
IF YOU ARE STUCK,PING ME AT
@MANUELMALYNO REALLY. DO IT!
![Page 76: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/76.jpg)
THANKS FOR LISTENING!COMING SOON: PART II INCLUDINGMVVM PATTERN AND MORE CODE
![Page 77: ReactiveCocoa Goodness - Part I of II](https://reader031.vdocuments.us/reader031/viewer/2022020217/54949ca1b47959794d8b4b58/html5/thumbnails/77.jpg)
@MANUELMALYCREATIVEPRAGMATICS.COM