我的方法在专用队列中运行其代码,完成后将调用传入的回调。是否需要检查传入的回调是否打算从主队列运行?
例如
- (void)doSomethingWithCalback:(void(^)())callback {
dispatch_async(self.privateQueue, ^{
// Should I make sure this gets dispatched
// to a main thread if it was passed in from a main thread?
if (callback) callback();
});
}
我是否应该执行以下操作:
- (void)doSomethingWithCalback:(void(^)())callback {
BOOL isMainThread = [NSThread isMainThread];
dispatch_async(self.privateQueue, ^{
if (callback) {
if (isMainThread) {
dispatch_async(dispatch_get_main_thread, callback);
}
else {
callback();
}
}
});
}
最佳答案
尽管没有在任何地方对此进行规定,但是如果您查看Cocoa API,则会看到三种常见的模式:
CLGeocoder
asynchronous query methods,其中“您的完成处理程序块将在主线程上执行”。 requestAccessForEntityType
的CNContactStore
,the documentation says“在任意队列上调用完成处理程序。” [NSURLSession sessionWithConfiguration:delegate:queue:]
,则可以指定将哪个队列用于委托方法和回调块/关闭。 (但是,顺便说一句,如果您不指定队列,它会使用自己的设计方法,而不是默认使用主队列。)但是,您提出的模式没有遵循任何这些非正式约定,而是有时使用主线程(如果您碰巧从主线程调用它),但有时则使用一些任意队列。在这种情况下,我认为没有必要引入新的约定。
我建议选择以上方法之一,然后在已发布的API中明确说明。例如,如果您要使用
privateQueue
:@interface MyAPI : NSObject
/// Private queue for callback methods
@property (nonatomic, strong, readonly) dispatch_queue_t privateQueue;
/// Do something asynchronously
///
/// @param callback The block that will be called asynchronously.
/// This will be called on the privateQueue.
- (void)doSomethingWithCallback:(void(^)())callback;
@end
@implementation MyAPI
- (void)doSomethingWithCallback:(void(^)())callback {
dispatch_async(self.privateQueue, ^{
if (callback) callback();
});
}
@end
要么
@interface MyAPI : NSObject
/// Private queue used internally for background processing
@property (nonatomic, strong, readonly) dispatch_queue_t privateQueue;
/// Do something asynchronously
///
/// @param callback The block that will be called asynchronously.
/// This will be called on the main thread.
- (void)doSomethingWithCallback:(void(^)())callback;
@end
@implementation MyAPI
- (void)doSomethingWithCallback:(void(^)())callback {
dispatch_async(self.privateQueue, ^{
if (callback) {
dispatch_async(dispatch_get_main_queue(), ^{
callback();
});
}
});
}
@end
请注意,无论使用哪种约定,我建议在标题中使用
///
注释或/** ... */
注释,以便在代码中使用该方法时,可以在右侧的快速帮助面板中看到队列行为。关于ios - 在专用队列上运行任务并返回回调,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35256182/