I have a thread safety question in the following code example from Apple (from the GameKit programming guide)
This is for downloading achievements from the game center and saving it locally:
Step 1) Add a mutable dictionary property to your class that reports achievements. This dictionary stores a collection of achievement objects.
@property(nonatomic, retain) NSMutableDictionary *achievementsDictionary;
Step 2) Initialize the dictionary of achievements.
achievementsDictionary = [[NSMutableDictionary alloc] init];
Step 3) Modify your code that loads load achievement data to add achievement objects to the dictionary.
{ [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) { if (error == nil) { for (GKAchievement* achievement in achievements) [achievementsDictionary setObject: achievement forKey: achievement.identifier]; } }];
My question is this: the successDictionary object changes in the completion handler without any sort locks. Is this allowed since completion handlers are a unit of work that will be guaranteed by iOS that will execute as a unit in the main thread? And never run into thread safety issues?
In another sample Apple code (GKTapper), this part is handled differently:
@property (retain) NSMutableDictionary* earnedAchievementCache;
Then in the handler:
[GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error) { if(error == NULL) { NSMutableDictionary* tempCache= [NSMutableDictionary dictionaryWithCapacity: [scores count]]; for (GKAchievement* score in scores) { [tempCache setObject: score forKey: score.identifier]; } self.earnedAchievementCache= tempCache; } }];
So, why is another style one of the ways more correct than the other?