菜鸟教程小白 发表于 2022-12-13 14:04:48

ios - 在私有(private)队列上运行任务并返回回调


                                            <p><p>我的方法在私有(private)队列中运行其代码,完成后将调用传入的回调。是否需要检查传入的回调是否打算从主队列运行?</p>

<p>例如</p>

<pre><code>- (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();
    });
}
</code></pre>

<p>我应该执行以下操作吗:</p>

<pre><code>    - (void)doSomethingWithCalback:(void(^)())callback {
      BOOL isMainThread = ;
      dispatch_async(self.privateQueue, ^{
            if (callback) {
               if (isMainThread) {
               dispatch_async(dispatch_get_main_thread, callback);
               }
               else {
               callback();
               }
            }
      });
    }
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>虽然这在任何地方都没有规定,但如果您查看 Cocoa API,您会看到三种常见模式:</p>

<ol>
<li><p><strong>主线程:</strong> 明确指定将使用主队列的完成处理程序。例如,引用 <code>CLGeocoder</code> <a href="https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLGeocoder_class/index.html#//apple_ref/occ/instm/CLGeocoder/reverseGeocodeLocation:completionHandler:" rel="noreferrer noopener nofollow">asynchronous query methods</a> ,其中“您的完成处理程序 block 将在主线程上执行。”</p></li>
<li><p><strong>任意队列:</strong>完成处理程序,您无法保证代码将在哪个队列运行。例如,如果您使用 <code>CNContactStore</code> 的 <code>requestAccessForEntityType</code>,<a href="https://developer.apple.com/library/ios/documentation/Contacts/Reference/CNContactStore_Class/index.html#//apple_ref/occ/instm/CNContactStore/requestAccessForEntityType:completionHandler:" rel="noreferrer noopener nofollow">the documentation says</a> “在任意队列上调用完成处理程序。”</p></li>
<li><p><strong>指定队列:</strong>完成处理程序,您可以在其中指定要使用的队列。例如,如果您使用 <code></code>,您可以指定哪个队列将用于委托(delegate)方法和回调 block /闭包。 (但是,顺便说一句,如果您不指定队列,它会使用自己的设计,而不是默认为主队列。)</p></li>
</ol>

<p>但是,您提出的模式不遵循任何这些非正式约定,而是有时使用主线程(如果您碰巧从主线程调用它),但有时使用一些任意队列。在这种情况下,我认为没有必要引入新的约定。</p>

<p>我建议选择上述方法之一,然后在已发布的 API 中明确说明。例如,如果您要使用 <code>privateQueue</code>:</p>

<pre><code>@interface MyAPI : NSObject

/// Private queue for callback methods

@property (nonatomic, strong, readonly) dispatch_queue_t privateQueue;

/// Do something asynchronously
///
/// @param callbackThe 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
</code></pre>

<p>或者</p>

<pre><code>@interface MyAPI : NSObject

/// Private queue used internally for background processing

@property (nonatomic, strong, readonly) dispatch_queue_t privateQueue;

/// Do something asynchronously
///
/// @param callbackThe 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
</code></pre>

<p>注意,无论您使用哪种约定,我都建议您在标题中使用 <code>///</code> 注释或 <code>/** ... */</code> 注释,这样当您使用代码中的方法,您可以看到右侧快速帮助面板中显示的队列行为。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在私有(private)队列上运行任务并返回回调,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35256182/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35256182/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在私有(private)队列上运行任务并返回回调