什么是首选:用GCD实现方法然后只是简单的调用,或实现方法然后用GCD调用它?

时间:2013-08-04 07:43:02

标签: iphone objective-c multithreading ipad grand-central-dispatch

什么是编写多线程应用程序的更优选方式。我看到两种方式。 用GCD实现方法然后只需简单调用(myMethodA),或者只是实现方法然后用GCD调用它?提前谢谢。

我的观点:

ClassA / method implementation

- (void)myMethodA
{
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //  doSomething1
    //  doSomething2
  });
}

- (void)myMethodB
{
  //  doSomething1
  //  doSomething2

}

ClassB / method call
{
  [myClassA methodA];
  // or
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     [myClassA methodB];
  };
}

3 个答案:

答案 0 :(得分:4)

恕我直言,两者都没有。

首选方法应该是拥有一个对象,它知道 where 来执行其操作:

completion_block_t completionHandler = ^(id result) { ... };
AsyncOperation* op = [AsyncOperation alloc] initWithCompletion:completionHandler];
[op start];  // executes its actions on a private execution context

然后,可以将这些AsyncOperation对象包装成一个方便的方法:

- (void) fetchUsersWithCompletion:(completion_block_t)completionHandler  
{
    NSDictionary* params = ...;
    self.currentOperation = [[HTTPOperation alloc] initWithParams:params
                                                      completion:completionHandler];
    [self.currentOperation start];
}

客户端可能只对指定其中应该执行其completionHandler感兴趣。 API可以增强如下:

- (void) fetchUsersWithQueue:(NSOperationQueue*)handlerQueue 
              withCompletion:(completion_block_t)completionHandler 
{
    NSDictionary* params = ...;

    self.currentOperation = [[HTTPOperation alloc] initWithParams:params
                                                      completion:^(id result){
        // As per the documentation of HTTPOperation, the handler will be executed
        // on an _unspecified_ execution context.
        // Ensure to execute the client's handler on the specified operation queue:
        [handlerQueue:addOperationWithBlock:^{
            completionHandler(result);
        }];
    }];
    [self.currentOperation start];
}

后一种API可以这样使用:

[self fetchUsersWithQueue:[NSOperation mainQueue] completion:^(id result){
    self.users = result;
    [self.tableView reloadData];
}];

答案 1 :(得分:0)

个人偏好。选择使代码更易读/可理解/明显的代码。另外,考虑代码是否应该可以在'当前'线程上运行,或者是否应该始终在后台线程上运行。您需要设计线程配置,描述它,然后考虑到这一点。如果你在类之间调用方法,那么我通常会说任何线程应该在该类内部处理,而不是在调用类中。但那是关于知识的分配。

答案 2 :(得分:0)

它没有太大的区别 - 它只取决于你想做什么。 如果您希望每次都在不同的队列上执行该方法,那么myMethodB系统更合适。但是,如果您总是希望在同一队列上运行该方法,那么myMethodA将节省您编写代码的时间(您只需编写一次GCD代码)。