Недавно я изменил существующий проект и изменил некоторые методы, возвращающие значение (BOOL) для вызова блока завершения. Я последовал за этим очень хорошим ответом:
{ ссылка }
Теперь у меня есть метод, который вызывает блок завершения, он отлично работает, но я боюсь, что может непредсказуемо потерпит неудачу из-за того, что не является потокобезопасным.
У меня есть объявление блока:
typedef void(^myCompletion)(id, BOOL);
Ниже приведен мой метод с обработчиком завершения:
-(void)myMethodThatTakesAnArgument:(id)object completionHandler:(myCompletion)completionblock {
//do things that are allowed in the main thread:
//...
//...
dispatch_queue_t backgroundQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(backgroundQueue, ^{
[self doWorkButReturnImmediately];
BOOL workIsNotFinished = [self isJobFinished];
NSDate *processingStart = [NSDate date];
NSTimeInterval timeElapsed = 0.0;
while (workIsNotFinished && timeElapsed < 15.0) {
[NSThread sleepForTimeInterval:1.0];
timeElapsed = [[NSDate date] timeIntervalSinceDate:processingStart];
workIsNotFinished = [self isJobFinished];
}
dispatch_async(dispatch_get_main_queue(), ^{
// Return Result
completionblock(object,YES);
});
});
}
Ниже приводится мой метод вызывающего абонента:
- (void)callerMethod {
NSArray *arrayOfObjects = [self prepareArrayOfObjects];
NSMutableArray *unprocessedObjects = [arrayOfObjects mutableCopy];
for (NSString *string in arrayOfObjects) {
[self myMethod:string completionblock:^(id obj, BOOL success) {
[unprocessedObjects removeObject:string];
if(success){
// do something with obj
NSLog(@"success");
}
if ([unprocessedObjects count] == 0) {
dispatch_async(dispatch_get_main_queue(), ^{
// Everything is done, act accordingly.
});
}
}
}
}
Я подозреваю, что этот сценарий может каким-то образом потерпеть неудачу, и я думаю добавить некоторый код безопасности потоков. Я не очень разбираюсь в этом предмете, но мне кажется, что, вероятно, @synchronized может быть путем к go. Поэтому я хотел бы встроить код вызываемого метода в некоторые операторы @synchronized, но я не уверен, нужно ли это в данном случае, и, если это так, я не уверен, где конкретно разместить операторы, я думаю, вероятно, в той части, которая отправляется в фоновой очереди. В код я включил простой объект, который передается обратно в обработчик завершения, который может действовать как объект, передаваемый в @synchronized. Любая помощь приветствуется. Спасибо