मैं (GameKit प्रोग्रामिंग गाइड से) एप्पल से निम्न उदाहरण कोड की धागा सुरक्षा के बारे में एक सवाल हैपूरा होने हैंडलर में परिवर्तनशील वस्तु को संशोधित करना
यह खेल के केंद्र से उपलब्धियां लोड और इसे स्थानीय स्तर पर बचाने के लिए है:
चरण 1) उपलब्धियों की रिपोर्ट करने वाली अपनी कक्षा में एक म्यूटेबल शब्दकोश प्रॉपर्टी जोड़ें। यह शब्दकोश उपलब्धि वस्तुओं के संग्रह को संग्रहीत करता है।
@property(nonatomic, retain) NSMutableDictionary *achievementsDictionary;
चरण 2) उपलब्धियों शब्दकोश को आरंभ करें।
achievementsDictionary = [[NSMutableDictionary alloc] init];
चरण 3) अपने कोड को संशोधित करें जो उपलब्धि वस्तुओं को लोड करने के लिए उपलब्धियों को लोड करता है।
{
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error)
{
if (error == nil)
{
for (GKAchievement* achievement in achievements)
[achievementsDictionary setObject: achievement forKey: achievement.identifier];
}
}];
मेरा प्रश्न इस प्रकार है - achievementsDictionary वस्तु प्रकार के किसी भी ताले के बिना, पूरा होने हैंडलर में संशोधित किया जा रहा है। क्या यह अनुमति है क्योंकि पूरा करने वाले हैंडलर काम का एक ब्लॉक है जिसे मुख्य थ्रेड पर इकाई के रूप में निष्पादित करने के लिए आईओएस द्वारा गारंटी दी जाएगी? और कभी थ्रेड सुरक्षा मुद्दों में भाग नहीं? हैंडलर में फिर
@property (retain) NSMutableDictionary* earnedAchievementCache; // note this is atomic
:
एक और एप्पल नमूना कोड (GKTapper) में, इस भाग को अलग ढंग से नियंत्रित किया जाता है
[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;
}
}];
तो क्यों अलग शैली है, और एक तरह से अधिक सही है इसके अलावा?
धन्यवाद जेरेमी। मैं आम तौर पर ब्लॉक समापन हैंडलर के बारे में भी पूछताछ कर रहा था। यदि प्रलेखन स्पष्ट रूप से कहता है कि पूरा करने वाले हैंडलर कहां कहलाता है, तो क्या यह मानना सुरक्षित है कि इसे मुख्य धागे में नहीं कहा जाता है? यदि इसे मुख्य कतार से बुलाया जाना है, तो थ्रेड सुरक्षा के बारे में चिंता किए बिना अंदर कुछ भी करना सुरक्षित है (मान लीजिए कि सभी एक्सेस मुख्य धागे या शिकायत हैंडलर मुख्य कतार पर बुलाए गए हैं)। –
यदि यह निर्दिष्ट नहीं करता है कि आपका ब्लॉक मुख्य कतार/थ्रेड पर कॉल किया जाएगा, तो आपको यह सुनिश्चित करने के लिए अपने स्वयं के उपाय करना होगा, यदि आपको यही चाहिए। इसे वास्तव में मुख्य धागे पर बुलाया जा सकता है, लेकिन उस बिंदु पर, यह तथ्य एक कार्यान्वयन विस्तार है, एपीआई अनुबंध का हिस्सा नहीं है, और चेतावनी के बिना बदल सकता है। यदि इसे मुख्य कतार से बुलाया जाता है, तो आप इसका पूरा लाभ ले सकते हैं। –
तब एक आखिरी सवाल - यदि मैं dispatch_async (dispatch_get_main_queue(),^{(GKAchievement * उपलब्धियों में उपलब्धि) के लिए पहला पूरा करने वाला हैंडलर बदलता हूं [achievementsDictionary setObject: उपलब्धि के लिए उपलब्धि: उपलब्धि। पहचानकर्ता];});) यह होगा कोड थ्रेडसेफ भी हो सकता है? मुझे इस बारे में कुछ याद रखना याद नहीं है .. –