从GCDWebServer请求处理程序访问可变数据

时间:2016-06-03 20:45:00

标签: ios multithreading nsmutabledictionary gcdwebserver

我偶尔会在我的GCDWebServer处理程序中崩溃,这些处理程序访问可变字典。 GCDWebServer自述文件说处理程序"是在GCD中的任意线程上执行的,因此必须特别注意线程安全性和重入性,"而且我认为这是我的问题。是否有从处理程序访问父对象的可变属性的最佳实践或推荐模式?

我不知道我是否可以在线程之间进行同步,因为我没有创建处理程序线程。另外,我想我可以使用异步处理程序,然后从那里调用主线程上的方法,然后在该方法中完成我的工作,然后发送响应,但这似乎更复杂,效率低于必要。

这是我的代码的简化版本:

@property (nonatomic, strong) NSMutableDictionary *data;
@property (nonatomic, strong) GCDWebServer *webServer;

- (void)setup {
    self.data = [NSMutableDictionary dictionary];
    [self.data setObject:@"1" forKey:@"status"];

    self.webServer = [[GCDWebServer alloc] init];
    [self.webServer addHandlerForMethod:@"GET" path:@"/getStatus.txt" requestClass:[GCDWebServerRequest class] processBlock:^(GCDWebServerRequest *request) {
        return [self handleStatusRequest:request];
    }];
}

- (GCDWebServerDataResponse *)handleStatusRequest:(GCDWebServerRequest *)request {
    NSString *status = [self.data objectForKey:@"status"]; // crash here
    return [GCDWebServerDataResponse responseWithText:status];
}

1 个答案:

答案 0 :(得分:1)

在创建后,您是否在改变data字典?如果这样可以解释崩溃。

您必须使用锁来阻止对data字典的并发访问。最简单的方法是通过GCD,例如

@property dispatch_queue_t lock;

__block NSString* status;
dispatch_sync(self.lock, ^{
  status = [self.data objectForKey:@"status"];
});

NSString* status = @"Hello";
dispatch_async(self.lock, ^{
  [self.data setObject:status forKey:@"status"];
});  // Use dispatch_sync() or dispatch_async() here depending on your needs