谁能告诉目标c中的块执行流程? [英] can anyone tell flow of execution of blocks in objective c?

查看:42
本文介绍了谁能告诉目标c中的块执行流程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,iam在Objective-c中与Blocks合作.我刚刚学习了语法,以及如何编写块.但是我不明白执行流程.我在Google上搜索了执行流程,但找不到.

Hi iam working with Blocks in objective-c. I have just learn syntax, and how to write blocks. But i didn't understand execution flow. I googled it for flow of execution, i can't find.

我使用了以下代码:

@interface NSArray (Extended)
- (NSArray *)each:(void (^)(id))block;
@end

@implementation NSArray (Extended)
- (NSArray *)each:(void (^)(id object))block {
for(id mObject in self)
    block(mObject);
return self;
}
@end

int main (int argc, const char * argv[]) {
@autoreleasepool {

  NSArray *array = [NSArray arrayWithObjects:@"Number one", @"Number two", nil];
  [array each:^(id object) {
     NSLog(@"obj: %@", object);
  }];

}
return 0;
}

谁能解释一下Objective-c中块执行的流程是什么?

Can anyone explain what is the flow of execution of blocks in objective-c?

推荐答案

不确定您要如何解释.这是我的尝试:

Not sure how you want to explain the thing. Here is my attempt:

块是一段代码.当使用^{}创建块时,该代码可以存储在变量中.在您的情况下(大多数情况下),它会像其他任何值一样立即作为参数传递给方法.该示例块声明了1个参数,在执行代码时必须指定其值 .变量object_in 包含一些对象,您可以在代码块中使用它.

Block is a piece of code. When you create a block using ^{}, that code can be stored in variable. In your case (and in most of the cases) it is immediatelly passed to method as argument, just like any other value. This example block declares 1 argument, whose value must be specified when the code will be executed. Variable object_in will contain some object and you can work with it in the block of code.

[array each:^(id object_in) {
    NSLog(@"object: %@", object_in);
}];

在方法内部,代码存储在自变量(在您的情况下为block)中.现在您要执行代码.您可以通过在括号中附加实际值列表作为块参数来实现.现在object_out包含一些实际值,因此它将被传递给object_in.

Inside of the method, the code is stored in argument variable, named block in your case. Now you want to execute the code. You do it by appending parentesis with the list of real values as block arguments. Now object_out contains some real value and so it will be passed to object_in.

- (NSArray *)each:(void (^)(id))block {
    for (id object_out in self) {
        block(object_out); // executes the code of block with given argument
    }
    return self;
}

现在,您的NSLog语句将与数组中的每个对象一起执行.

Now your NSLog statement is executed with every object in the array.

它与函数指针非常相似.如果您对此有所了解,则可能会更容易,如果不了解,请不要担心:)

It is very similar to function pointer. If you know something about it, is may be easier, if not, don't bother with that :)

因此,您可以按参数将值传递给块,但是还有第二种方法来使值进入块.它是关于捕获局部变量的,但是在您的示例中未使用它.如果您或其他任何人想让我解释一下,请随时发表评论.

So you can pass values to block by arguments, but there is also second way to get values into block. It is about capturing local variables, but it is not used in your example. If you or anyone else wanted me to explain it, feel free to comment.

编辑:所以这里是捕获变量的简要说明. {}中包含的每一段代码都是 scope ,因此block也是一个作用域.作用域是嵌套的,并且在它们中创建的局部变量仅在控制流离开作用域之前才有效.子作用域可以使用父作用域中的变量.

So here is light explanation for captured variables. Every piece of code enclosed in {} is scope and so block is also a scope. Scopes are nested and local variables created in them are valid only until the control flow leaves the scope. Child scopes can use variables from parent scope.

示例代码迭代两个数组,一个通过for-in循环,第二个通过-each:方法.现在,作为参数传递的块稍有不同–它使用了父作用域中的一个变量(实际上是祖父母作用域中的变量).为什么此块与众不同?方法-each:将执行多次,每次string包含不同的值.换句话说,将创建3个该块的实例,每个实例具有其自己的string值.

Example code below iterates two arrays, one by for-in loop and second by -each: method from the question. The block passed as argument is now slightly different – it uses one variable from the parent scope (in fact it's from grandparent scope). Why is this block different? The method -each: will be executed multiple times, every time with string containing different value. In another words, 3 instances of the block will be created each with its' own string value.

NSArray *strings = @[ @"A", @"B", @"C" ];
NSArray *numbers = @[ @1, @2, @3 ];

NSString *string = nil; // doing this to be more obvious
for (string in strings) {
    // string is simple local variable
    [numbers each:^(id number) {
        // number is argument
        NSLog(@"argument: %@, captured: %@", number, string);
    }];
}

输出:

argument: 1, captured: A
argument: 2, captured: A
argument: 3, captured: A
argument: 1, captured: B
argument: 2, captured: B
argument: 3, captured: B
argument: 1, captured: C
argument: 2, captured: C
argument: 3, captured: C

因此,我们有所有3个实例共有的代码,并且每个实例的某些变量(可能)不同.如果这使您想起类/对象关系,那您是对的.

So we have code, that is common to all 3 instances and some variable that is (can be) different for each of them. If this reminds you of class / object relationship, you are right.

对于块的每次调用,参数都不同(如先前的代码示例所示),并且对于每个实例,捕获的变量也不同.每次执行带有块定义(^{)的行时,都会创建一个新实例.

Argument is different for each invocation of the block (shown in previous code examples) and captured variables are different for each instance. New instance is created every time the line with block definition (^{) is executed.

这篇关于谁能告诉目标c中的块执行流程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆