当前位置:  开发笔记 > IOS > 正文

iPhone使用具有异步URL请求的互斥锁

如何解决《iPhone使用具有异步URL请求的互斥锁》经验,为你挑选了2个好方法。

我的iPhone客户端很多涉及异步请求,很多时候一直在修改字典或数组的静态集合.因此,我常常看到更大的数据结构需要更长的时间从服务器检索并出现以下错误:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection  was mutated while being enumerated.'

这通常意味着对服务器的两个请求返回了试图修改同一集合的数据.我正在寻找的是如何正确构建我的代码以避免这种有害错误的教程/示例/理解.我相信正确的答案是互斥体,但我从来没有亲自使用它们.

这是使用NSURLConnection发出异步HTTP请求,然后在请求完成后使用NSNotification Center作为委派方式的结果.当触发改变相同集合集的请求时,我们会发生这些冲突.



1> sbooth..:

有几种方法可以做到这一点.在您的情况下最简单的可能是使用@synchronized指令.这将允许您使用任意对象作为锁来动态创建互斥锁.

@synchronized(sStaticData) {
  // Do something with sStaticData
}

另一种方法是使用NSLock类.创建您想要使用的锁,然后在获取互斥锁时会有更多的灵活性(如果锁不可用则关闭阻塞等).

NSLock *lock = [[NSLock alloc] init];
// ... later ...
[lock lock];
// Do something with shared data
[lock unlock];
// Much later
[lock release], lock = nil;

如果您决定采用这些方法中的任何一种,则必须获取读取和写入的锁定,因为您使用NSMutableArray/Set/whatever作为数据存储.正如您所见,NSFastEnumeration禁止枚举对象的变异.

但我认为这里的另一个问题是在多线程环境中选择数据结构.是否必须从多个线程访问您的词典/数组?或者后台线程是否可以合并它们接收的数据,然后将其传递给主线程,主线程是唯一允许访问数据的线程?



2> Andrew Grant..:

如果可能同时从两个线程访问任何数据(包括类),则必须采取措施使这些数据保持同步.

幸运的是,Objective-C使用synchronized关键字很容易实现.此关键字将任何Objective-C对象作为参数.在同步部分中指定相同对象的任何其他线程将暂停,直到第一个完成.

-(void) doSomethingWith:(NSArray*)someArray
 {    
    // the synchronized keyword prevents two threads ever using the same variable
    @synchronized(someArray)
    {
       // modify array
    }
 }

如果您需要保护的不仅仅是一个变量,您应该考虑使用表示访问该组数据的信号量.

// Get the semaphore.
id groupSemaphore = [Group semaphore];

@synchronized(groupSemaphore) 
{
    // Critical group code.
}

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有