2014-06-28 79 views
0

我有一個NSMutableArray我需要添加對象從我調度的多個塊。這是一個可接受的方式來確保數組安全地被更改?這些已經從內部和NSOperation派出,並在後臺運行。我正在連續加載該線程中的數據,但一次加載位置列表變得非常緩慢。如何安全地使用GCD鎖定變量?

NSMutableArray *weatherObjects = [[NSMutableArray alloc] init]; 
ForecastDownloader *forecastDownloader = [[ForecastDownloader alloc] init]; 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_group_t group = dispatch_group_create(); 

dispatch_queue_t serialQueue; 
serialQueue = dispatch_queue_create("us.mattshepherd.ForecasterSerialQueue", NULL); 

for (NSDictionary *theLocation in self.weatherLocations) { 

    // Add a task to the group 
    dispatch_group_async(group, queue, ^{ 
     NSLog(@"dispatching..."); 
     int i = 0; 
     WeatherObject *weatherObject = [forecastDownloader getForecast:[theLocation objectForKey:@"lat"] lng:[theLocation objectForKey:@"lng"] weatherID:[[theLocation objectForKey:@"id"] intValue]]; 

     } 
     if(!weatherObject){ 
      //need to implement delegate method to show problem updating weather 
      NSLog(@"problem updating weather data"); 
     }else{ 
      NSLog(@"got weather for location..."); 
      dispatch_sync(serialQueue, ^{ 
       [weatherObjects addObject:weatherObject]; 
      }); 


     } 
    }); 

} 
// wait on the group to block the current thread. 
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"finished getting weather for all locations..."); 
//we will now do something with the weatherObjects 

回答

1

這是行不通的,因爲你每次做一個新的鎖,而不是使用一個單一的鎖變量(類比:假如一個鎖着的門到房間,如果每個人都有自己的門。一把鎖,鎖定它並不重要,因爲其他人都會進入自己的門)。

您可以爲所有迭代使用單個NSLock,或者(基本上等同於)一個串行調度隊列。

+0

我編輯它,這現在是否安全嗎? – Matt

+0

是的,看起來不錯。如果您不使用ARC,請記住dispatch_release串行隊列。 –