Last active
April 5, 2019 17:44
-
-
Save rnapier/9e183635d3c7d26483d2ef797cf4ccec to your computer and use it in GitHub Desktop.
GCD accessor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// test | |
// | |
// Created by Rob Napier on 4/5/19. | |
// | |
#import <Foundation/Foundation.h> | |
@interface MyClass: NSObject | |
@property (nonatomic, readwrite, copy) NSString *name; | |
@end | |
@interface MyClass() | |
// I often just use one queue for the whole object, but you can also | |
// split things out so each property has its own queue. | |
@property (nonatomic, readwrite, strong) dispatch_queue_t queue; | |
@end | |
@implementation MyClass { | |
NSString *_name; // Make a backing ivar | |
} | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self) { | |
// Standard concurrent queue | |
_queue = dispatch_queue_create("MyClass", DISPATCH_QUEUE_CONCURRENT); | |
} | |
return self; | |
} | |
- (NSString *)name { | |
// We have to block here (_sync), but since this is concurrent we will only | |
// be blocked if there's a write queued up. | |
__block NSString *result; | |
dispatch_sync(self.queue, ^{ | |
result = self->_name; | |
}); | |
return result; | |
} | |
- (void)setName:(NSString *)name { | |
// Barrier says that this block can't start until all previous blocks have finished | |
// and no later blocks may start until this block is done. Make it fast. That's why | |
// we do the copy before going into the barrier. | |
// All reads that were submitted before this write will see the old value, and all | |
// reads that were submitted after this write will see the new value. | |
NSString *copy = [name copy]; | |
dispatch_barrier_async(self.queue, ^{ | |
self->_name = copy; | |
}); | |
} | |
@end | |
int main(int argc, const char * argv[]) { | |
@autoreleasepool { | |
MyClass *x = [MyClass new]; | |
x.name = @"Alice"; | |
NSLog(@"Hello, %@!", x.name); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment