sub*_*arb 5 objective-c grand-central-dispatch
我在这里有点困惑,我使用队列,我到了一点,我有点迷失.
我有一个名为getPeoplewho 的方法,必须从服务器获取用户的图片.为了不阻止应用程序,我使用了这个:
-(IBAction)seeMorePeople{
dispatch_queue_t getPeopleQueue = dispatch_queue_create("Pinta Ocupantes", NULL);
dispatch_async(getPeopleQueue, ^{
[self getPeople];
});
dispatch_release(getPeopleQueue);
}
Run Code Online (Sandbox Code Playgroud)
每次用户点击按钮时都会执行上一个代码.像"从这张专辑给我照片"然后另一个点击"现在我想要来自其他专辑的人物照片",不同的照片和不同数量的照片.如果用户非常快地点击按钮,则第一个队列在第二个队列已经启动时不会完成获取数据.在getPeople我将数据存储在NSMutableArray中时,所以当两个队列同时执行时,两个队列都在同一个数组上写入,并且应用程序因超出范围异常而崩溃.getPeople通过数据的方式是这样的:
-(void)getPeople:(NSDictionary *)peopleDictionary{
//I receive an NSDictionary and I go through it
NSArray *keys = [peopleDictionary allKeys];
int indexOfArray = 0;
for(NSString *key in keys){
//Complex operation that are not important
[peopleInArray insertObjetAtIndex:indexOfArray];//People in array is a global variable
indexOfArray++;
}
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚的是如何摆脱这种情况,我想在第二个队列进入时停止第一个队列,但是GCD没有这个选项...任何其他方式来完成这个,希望没有专业重新编码,无论如何我现在没有想法,所以任何线索都会有所帮助.
如果可能的话,我建议您避免与信号量同步.GCD的设计是为了避免这种情况.后台任务应该准备数据但不要触摸外部状态.在准备数据时,它应该将外部状态的更新分派给串行队列,或者如果状态绑定到GUI,则分配给主队列.
所以,像这样:
-(void)getPeople:(NSDictionary *)peopleDictionary{
//I receive an NSDictionary and I go through it
NSArray *keys = [peopleDictionary allKeys];
for(NSString *key in keys){
//Complex operation that are not important
dispatch_async(dispatch_get_main_queue(), ^{
[peopleInArray addObject:<whatever>];
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想要替换数组,而不是以交错方式添加两个线程,则可以在后台累积整个数组,并将整个数据集设置peopleInArray到主队列中.
如果你想要取消,你可以用旗子自己实现,或者你应该考虑使用NSOperation而NSOperationQueue不是GCD.虽然您的自定义操作仍然需要检查它们是否已被取消并停止工作,但它们具有内置取消的概念.
| 归档时间: |
|
| 查看次数: |
13871 次 |
| 最近记录: |