Cocoa 如何使用GCD安全地锁定变量?

Cocoa 如何使用GCD安全地锁定变量?,cocoa,concurrency,grand-central-dispatch,Cocoa,Concurrency,Grand Central Dispatch,我有一个NSMutableArray,我需要从已调度的多个块向其中添加对象。这是一种可接受的方法来确保阵列安全地被更改吗?这些已从内部和NSO操作中调度,并在后台运行。我从该线程中串行加载数据,但一次加载位置列表的速度非常慢 NSMutableArray *weatherObjects = [[NSMutableArray alloc] init]; ForecastDownloader *forecastDownloader = [[ForecastDownloader alloc] init

我有一个NSMutableArray,我需要从已调度的多个块向其中添加对象。这是一种可接受的方法来确保阵列安全地被更改吗?这些已从内部和NSO操作中调度,并在后台运行。我从该线程中串行加载数据,但一次加载位置列表的速度非常慢

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

这是行不通的,因为你每次都要做一把新锁,而不是用一把锁作为变量(比方说:想象一个房间的门被锁上了。如果每个人都有自己的门,锁上它就不重要了,因为其他人都会从自己的门进来)


您可以对所有迭代使用单个NSLock,也可以(基本上等价地)使用单个串行调度队列。

是,看起来不错。如果不使用ARC,请记住释放串行队列。