比较目标C中的块和功能

水泡蛋白

当我学习目标C时,我的理解是新的且不完整。块的概念与功能非常相似。它们甚至看起来几乎相同:

功能名为“乘”

#import <Foundation/Foundation.h>

int multiply (int x, int y)
{

    return x * y;

}

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

        int result = multiply(7, 4); // Result is 28.
        NSLog(@"this is the result %u",result);

        }
}

名为“乘法”的块

#import <Foundation/Foundation.h>

int (^Multiply)(int, int) = ^(int num1, int num2) {

    return num1 * num2;
};

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

    @autoreleasepool {

        int result = Multiply(7, 4); // Result is 28.
        NSLog(@"this is the result %u",result);
    }
}

我在网络上发现了各种语句,例如:“块是作为Objective-C对象实现的,除了它们可以放在栈中,因此不必分配(如果您保留对块的引用,不过,它将被复制到堆上。”

雷·温德利希(Ray Wenderlich)说:“块是一流的功能”

我不知道这一切意味着什么。我的示例表明,同一功能可以通过块或功能来实现。有人可以举例说明块可以完成某些功能吗?或相反亦然?还是更微妙的事情,例如在内存中处理变量“结果”的方式?还是更快/更安全?它们中的任何一个都可以用作类定义中的方法吗?

谢谢。

igul222

块是Objective-C对象,而功能不是。实际上,这意味着您可以像这样从一个代码段到另一个代码传递一个块:

NSArray *names = @[@"Bob", @"Alice"];
[names enumerateObjectsUsingBlock:^(id name, NSUInteger idx, BOOL *stop) {
    NSLog(@"Hello, %@", name);
}];

在C语言中,可以通过传递指向函数的指针来实现类似的效果。但是,执行此操作和使用块之间的主要区别在于,块可以捕获值。例如,在上面的示例中,如果我们想使用可变问候语:

NSString *greeting = @"Hello";
NSArray *names = @[@"Bob", @"Alice"];
[names enumerateObjectsUsingBlock:^(id name, NSUInteger idx, BOOL *stop) {
    NSLog(@"%@, %@", greeting, name);
}];

在此示例中,编译器可以看到该块依赖于局部变量greeting,并将“捕获”该值greeting并将其与该块一起存储(在这种情况下,这意味着保留并存储指向NSString的指针)。无论该块最终在哪里使用(在这种情况下,在的实现中[NSArray -enumerateObjectsUsingBlock:]),它都可以访问该greetings变量,就像声明该块时一样。这使您可以在块范围内使用任何局部变量,而不必担心将它们传递到块中。

要在C中使用函数指针执行相同的操作,greeting必须将其作为变量传递。但是,这不会发生,因为调用方(在本例中为NSArray)无法确切知道(尤其是在编译时)必须将哪些参数传递给函数。即使这样做,您仍需要以某种方式将greetingNS的值以及您要使用的所有其他局部变量传递给NSArray,这会很快使您感到毛骨悚然:

void greet(NSString *greeting, NSString *name) {
    NSLog(@"%@, %@", greeting, name);
}

// NSArray couldn't actually implement this
NSString *greeting = @"Hello";
NSArray *names = @[@"Bob", @"Alice"];
[names enumerateObjectsUsingFunction:greet withGreeting:greeting];

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章