Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用iOS上的Grand Central Dispatch,如果常规Objective-C块不在调度队列中,它们运行在哪个队列(如果有)上?_Ios_Objective C_Multithreading_Objective C Blocks_Grand Central Dispatch - Fatal编程技术网

使用iOS上的Grand Central Dispatch,如果常规Objective-C块不在调度队列中,它们运行在哪个队列(如果有)上?

使用iOS上的Grand Central Dispatch,如果常规Objective-C块不在调度队列中,它们运行在哪个队列(如果有)上?,ios,objective-c,multithreading,objective-c-blocks,grand-central-dispatch,Ios,Objective C,Multithreading,Objective C Blocks,Grand Central Dispatch,下面的选项#1是否运行某种隐含队列?它似乎没有在主队列上运行,因为当我尝试更新那里的UI内容时,它一直抱怨,直到我移动到选项#3,所以我假设块有自己的队列或线程?在它抱怨之前,我的印象是,如果我不启动调度队列,事情就会像正常一样运行,在我看来,这将是在主队列上。下面是一些示例代码来说明: // UserViewController.h @interface UserViewController : NSObject @property(nonatomic, strong) Server *ser

下面的选项#1是否运行某种隐含队列?它似乎没有在主队列上运行,因为当我尝试更新那里的UI内容时,它一直抱怨,直到我移动到选项#3,所以我假设块有自己的队列或线程?在它抱怨之前,我的印象是,如果我不启动调度队列,事情就会像正常一样运行,在我看来,这将是在主队列上。下面是一些示例代码来说明:

// UserViewController.h
@interface UserViewController : NSObject
@property(nonatomic, strong) Server *server;
@property(nonatomic, strong) User *user;
@end

// UserViewController.m - Controller that sets a block for use in another class
@implementation UserViewController
- (void)doSomething {
  // I'd like to call other methods and set @properties from the controller and I've heard
  // __weak is the correct keyword to use (rather than __block or __strong).
  __weak UserViewController *weakController = self;

  // Option #0 - Outside of block
  weakController.user = [[RHZUser alloc] init];

  server.callbackBlock = ^(NSURLResponse *response, NSData *data, NSError *error) {

    // Option #1 - Outside of dispatch queues.  Is this in some sort of default queue?
    weakController.user = [[RHZUser alloc] init];

    dispatch_queue_t backgroundQueue
      = dispatch_queue_create("com.example.backgroundQueue", nil);

    dispatch_async(backgroundQueue, ^{

      // Option #2 - This is on the serial queue I created
      weakController.user = [[RHZUser alloc] init];

      dispatch_async(dispatch_get_main_queue(), ^{

        // Option #3 - The main queue where all my UI is
        weakController.user = [[RHZUser alloc] init];

      } // dispatch_async
    } // dispatch_async
  }; // self.callbackBlock
}
@end

// Server.m - Class that uses the block defined in the controller
@implementation Server
- makeAServerCall {
  [NSURLConnection sendAsynchronousRequest:
    [NSMutableURLRequest requestWithURL:restServiceURL]
                                  queue:[[NSOperationQueue alloc] init]
                      completionHandler:self.callbackBlock];
}
@end

可能是
Server
错误地(在我看来)在非主队列的队列上实现了回调块。您可以通过检查
[NSThread isMainThread]来检查选项#1是否绝对不在主队列上。通常只更改主线程上的
UIKit
元素(也有一些例外-一如既往!)


通常,web服务回调(或完成)块被发送回主线程,例如。

块是一段代码,执行时在特定队列上运行。在某个对象上设置块不会使其运行,也不会附加到某个特定队列

在选项1的情况下,可以在
服务器的实例上设置块特性。这并不意味着它已运行,它所做的只是让任何有权访问该块的人都可以访问该代码。因为属性的名称是
callbackBlock
,所以我假设
Server
实例在完成某项任务时执行块

这是当块绑定到队列时
Server
的实现决定它是否在主队列上运行,并且应该记录(可能在its.h中)它是否在主队列上运行。如果它没有文档记录,但我绝对需要它在主队列上运行,那么我总是安全地运行它,并通过将它包装在
dispatch\u async
中来确保它在主线程上被调用

编辑:

假设您的
服务器
实现与
服务器
相同,您可以使用alloc/init创建一个新队列,并将其传递给
NSURLConnection
。从
NSURLConnection
文档中:

排队

请求完成或失败时处理程序块被调度到的操作队列


因此,行为确实是有文档记录的,如果您希望在主队列上调用处理程序,只需传递
dispatch\u get\u main\u queue
,就可以调用一个块。与使用函数指针的调用相同;实际上与使用函数指针的语法相同。该块将与调用方在同一线程上运行

dispatch_block_t myBlock = ^ { NSLog (@"This is a block!"); };
myBlock (); 

在运行代码的同一线程上打印“thisablock!”。回调将在调用它们的任何线程上运行。因此,您的“选项1”块将在该块的调用者决定对其执行的任何队列上执行。通常,这应该通过使用回调的方法来记录。有一些使用回调的方法允许您传入队列,它们将在该队列上调度回调

块就是可以像函数一样调用的东西。他们不关心线程和队列本身,也不做任何事情。如果您问“在iOS上使用Grand Central Dispatch,如果常规C函数不在调度队列中,它们运行在什么队列(如果有的话)”或“在iOS上使用Grand Central Dispatch,如果常规Objective-C方法不在调度队列中,它们运行在什么队列(如果有的话)”时,您的问题将完全相同答案就是这个问题的标题

那么这些问题的答案是什么?嗯,函数(或方法或块)在调用时运行。就这么简单。所以根据定义,它在调用它时所处的任何线程或队列上运行。因此,块中的代码在哪个线程中运行取决于调用它的代码在哪个线程中。那么这个街区叫什么名字?该块被传递到
+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:],正是这段代码以某种方式调用了它。我们没有该库的代码,但是它的文档表明完成处理程序在作为第二个参数传入的
NSOperationQueue
中执行。将新的
NSOperationQueue
对象作为第二个参数传递


NSOperationQueue
维护运行操作的内部线程或调度队列。您无权访问并且不应关心此内部队列;您只知道这些操作是在与其他队列和线程分离的对象上执行的,因此肯定不是主线程。

这是被否决的特定原因吗?我很想知道为什么-我错过了或得到了一些不正确的东西吗?谢谢,我会尝试把代码放进去,看看它是否在主线程上。(P.S.反对票不是我投的。)@Tendiousjay是的,我不认为是你。。。!总是这样-你已经找到了解决问题的方法,但只是想知道为什么会发生这样的事情,所以我的答案不仅仅是一个解决方案,而是一句话p这里有
doSomething
从?K调用,我检查过了。选项#0和#3对于[NSThread isMainThread]是真的。因此选项#1(块中的代码)肯定运行在不同的线程上,但不确定它是否在某种默认队列中。(注意:选项#0最初不在我的问题中,为了清楚起见,我更新了我的答案以包含它。)哈,我在分配/初始化传递给NSURLConnection的NSOperationQueue的地方完全隔开(花了太多时间盯着UserViewController.m)。选项#1在传递给NSURLConnection的任何队列上运行完全有意义。我不确定我是否需要它在dispatch\u get\u main\u队列上运行,但建议使用+1。(newacct还提到了NSO操作