I recently added threading to an app so that network requests are not blocking the UI. On doing this, I discovered that I could no longer set my instance variable the same way as I had before implementing threading. My instance variable is a property declared as follows:
@property (nonatomic, strong) NSMutableArray *currentTopPlaces;
Here is how I incorrectly set my instance variable self.currentTopPlaces:
dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
__block NSArray *topPlaces = [FlickrFetcher topPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableRowCount = [topPlaces count];
[[self currentTopPlaces] setArray:topPlaces];
});
Using [self currentTopPlace] setArray:topPlaces] worked fine in the blocking version, before I started using GCD.
Now, I must set it like so for things to work correctly:
dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
__block NSArray *topPlaces = [FlickrFetcher topPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableRowCount = [topPlaces count];
self.currentTopPlaces = topPlaces;
});
Can someone explain to me the difference between using:
[[self currentTopPlaces] setArray:topPlaces];
and:
self.currentTopPlaces = topPlaces;
Specifically, why the “setArray” call did not work in a threaded block?
I thought dot notation in Objective-C is syntactic sugar and not mandatory. I would like to know the “non-sugared” way to achieve the same behavior.
[self currentTopPlaces]andself.currentTopPlacesare in fact identical, butare not. (1) replaces all elements of
self.currentTopPlaceswith those fromtopPlaces. (2) assigns a new value toself.currentTopPlaces(releasing the old value if it was not nil).A difference occurs if
self.currentTopPlacesis nil: (1) does nothing, because thesetArray:method is sent to nil. (2) assigns a new value toself.currentTopPlaces.Btw: The
__blockmodifier is not necessary in your code, because the block will not change the value oftopPlaces.