当我学习目标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)说:“块是一流的功能”
我不知道这一切意味着什么。我的示例表明,同一功能可以通过块或功能来实现。有人可以举例说明块可以完成某些功能吗?或相反亦然?还是更微妙的事情,例如在内存中处理变量“结果”的方式?还是更快/更安全?它们中的任何一个都可以用作类定义中的方法吗?
谢谢。
块是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)无法确切知道(尤其是在编译时)必须将哪些参数传递给函数。即使这样做,您仍需要以某种方式将greeting
NS的值以及您要使用的所有其他局部变量传递给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] 删除。
我来说两句