编译器是否保存函数的参数?

1 objective-c ios objective-c-blocks

我有一个函数,它使用GCD在另一个线程中通过索引加载图像.

所以我们假设:

-(void)loadMainImageToIndex:(long)index
{
    NSDictionary *dic=[mainData objectAtIndex:index];
    NSString *userImageUrl=[dic objectForKey:@"url"];
    NSURL *userUrl=[NSURL URLWithString:userImageUrl];
    [self downloadImageWithURL:userUrl completionBlock:^(BOOL succeeded, NSData *tdata)
     {
         if (succeeded)
         {

             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
                            {

                          //do something here 

                          dispatch_async(dispatch_get_main_queue(), ^
                                               {
                           //do something here that uses the index argument
Run Code Online (Sandbox Code Playgroud)

我称这个功能为3次:

[self loadMainImageToIndex:0];
[self loadMainImageToIndex:1];
[self loadMainImageToIndex:2];
Run Code Online (Sandbox Code Playgroud)

问题是,当第一次调用将结束线程操作时,将达到这一点:

dispatch_async(dispatch_get_main_queue()
Run Code Online (Sandbox Code Playgroud)

他会在那里看到index=0,还是他会看到最后一个指数called (==2)

问题是,他是否复制了整个函数,所以当他完成时他能记住启动该方法的论点?另外一件事,同时召唤它3次,是一种不好的做法吗?

谢谢.

Rob*_*ier 5

简短版:这里没问题.你做得很好,它的行为就像你期望的那样(每个块都有正确的值).

更长的版本:

-(void)loadMainImageToIndex:(long)index
Run Code Online (Sandbox Code Playgroud)

每次调用此方法都会将新的副本推index送到堆栈中.当方法返回时,它将被弹出(销毁).即使并行多次调用此方法(在不同的线程上),每个方法也会index在自己的堆栈上拥有自己的副本.局部变量和参数对于方法或函数的每次调用都是私有的.

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
Run Code Online (Sandbox Code Playgroud)

这里创建一个块"捕获"(复制)它在块中发现的所有变量.这包括index因为它被用于:

dispatch_async(dispatch_get_main_queue(), ^
Run Code Online (Sandbox Code Playgroud)

所以,这里没有问题.发送到主队列的块将具有自己的副本index,该副本在创建块时生成.封闭块index在创建时也创建了一个副本,并且该方法复制了传递给它的值index.

请注意,"创建块时" ^{}是评估的点,而不是dispatch_调用函数的点.这些函数接受一个块,它们不会创建块.创建一个块并将其存储在一个变量中然后将该块传递给其他东西是完全合法的(也是常见的).该块将在其创建的位置捕获(复制)其变量.这个概念称为闭包.