Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Less lulzy RAC-less parallel work example #391

Merged
merged 1 commit into from

2 participants

@joshaber
Owner

h/t @ddeville

@jspahrsummers

This is definitely Better Code™, but it strays from what this section was really meant to be about in my mind – namely, synchronization.

There are ways to avoid explicit synchronization without needing RAC, but they're often non-trivial. This was a poorly-chosen and poorly-written example on my part, so I think we should instead try to think of realistic Cocoa code that would use @synchronized (and would be difficult to write with operation queues), and rewrite that in a RAC-like way.

@joshaber
Owner

The section is titled "Parallelizing independent work." So if it was meant to be about synchronization, that's a pretty less than descriptive title :)

@jspahrsummers

Truuueeee. Alright, let's do it.

@jspahrsummers jspahrsummers merged commit 239c3e1 into master
@jspahrsummers jspahrsummers deleted the less-lulzy-example branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 23, 2013
  1. @joshaber
This page is out of date. Refresh to see the latest.
Showing with 22 additions and 21 deletions.
  1. +22 −21 README.md
View
43 README.md
@@ -382,31 +382,31 @@ synchronization:
```objc
__block NSArray *databaseObjects;
__block NSArray *fileContents;
-
-dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- @synchronized (self) {
- databaseObjects = [databaseClient fetchObjectsMatchingPredicate:predicate];
- if (fileContents != nil) {
- [self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
- NSLog(@"Done processing");
- }
- }
-});
-
-dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
+NSBlockOperation *databaseOperation = [NSBlockOperation blockOperationWithBlock:^{
+ databaseObjects = [databaseClient fetchObjectsMatchingPredicate:predicate];
+}];
+
+NSBlockOperation *filesOperation = [NSBlockOperation blockOperationWithBlock:^{
NSMutableArray *filesInProgress = [NSMutableArray array];
for (NSString *path in files) {
[filesInProgress addObject:[NSData dataWithContentsOfFile:path]];
}
-
- @synchronized (self) {
- fileContents = [filesInProgress copy];
- if (databaseObjects != nil) {
- [self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
- NSLog(@"Done processing");
- }
- }
-});
+
+ fileContents = [filesInProgress copy];
+}];
+
+NSBlockOperation *finishOperation = [NSBlockOperation blockOperationWithBlock:^{
+ [self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
+ NSLog(@"Done processing");
+}];
+
+[finishOperation addDependency:databaseOperation];
+[finishOperation addDependency:filesOperation];
+[backgroundQueue addOperation:databaseOperation];
+[backgroundQueue addOperation:filesOperation];
+[backgroundQueue addOperation:finishOperation];
```
The above code can be cleaned up and optimized by simply composing signals:
@@ -429,6 +429,7 @@ RACSignal *fileSignal = [RACSignal start:^(BOOL *success, NSError **error) {
combineLatest:@[ databaseSignal, fileSignal ]
reduce:^(NSArray *databaseObjects, NSArray *fileContents) {
[self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents];
+ return nil;
}]
subscribeCompleted:^{
NSLog(@"Done processing");
Something went wrong with that request. Please try again.