如何在 Objective-C 中编写 lambda 方法?
Posted
技术标签:
【中文标题】如何在 Objective-C 中编写 lambda 方法?【英文标题】:How to write lambda methods in Objective-C? 【发布时间】:2010-10-30 22:46:07 【问题描述】:【问题讨论】:
【参考方案1】:Objective-C 中的 lambda 概念现在被封装为 Blocks 的概念,相当于传递引用函数。当然,可以说在 C 语言中已经有了函数指针的概念。块只是捕获本地状态的一种方式(即可以是闭包)。事实上,块也可以在其他 C 语言中使用(在 Mac 上)——有一个建议是让它们成为标准 C 语法的一部分。
这是一个定义 lambda 以将两个数字相乘的示例:
int (^mult)(int, int) = ^(int a, int b) return a*b; ;
第一部分声明一个^int(int,int)
类型的变量,然后将其分配给返回其两个参数的倍数的lambda 表达式(又名块)。然后,您可以传递该 fn,在其他地方定义它等;您甚至可以在其他功能中使用它。
这是一个定义函数的示例,当调用该函数时,会返回另一个函数:
multiplyBy = ^(int a) return ^(int b) return b*a; ; ;
triple = multiplyBy(3);
请注意,您可以将块与对象类型混合(通常使用id
作为对象类型),并且许多新的 Objective-C 对象数据结构具有某种块级操作。 GCD 也使用块来传递任意事件;但是请注意,GCD 也可以与函数指针一起使用。
【讨论】:
另请注意,块支持已移植到 10.5 和带有似是而非块项目的 iPhone OS。 code.google.com/p/plblocks 注意 Blocks 可以在 ios 4 中使用,无需 Plausible Blocks 项目。 +1 'multiplyBy' AIBlue 的优秀示例,感谢您如此简洁地展示了块的灵活性。 ObjC 块类似于 Smalltalk 块,但不清楚 Objective C 中如何或是否可以定义、实现、传递、接受和调用任意类型的块。 在哪里声明 multiplyBy 的类型?【参考方案2】:OS X 10.6 引入了块。见AlBlue's answer for examples。
如果您不使用 Snow Leopard,则可以使用各种其他功能获得接近功能组合的东西。
使用 C 函数指针的示例:
void sayHello()
NSLog(@"Hello!");
void doSomethingTwice(void (*something)(void))
something();
something();
int main(void)
doSomethingTwice(sayHello);
return 0;
使用命令模式的示例:
@protocol Command <NSObject>
- (void) doSomething;
@end
@interface SayHello : NSObject <Command>
@end
@implementation SayHello
- (void) doSomething
NSLog(@"Hello!");
@end
void doSomethingTwice(id<Command> command)
[command doSomething];
[command doSomething];
int main(void)
SayHello* sayHello = [[SayHello alloc] init];
doSomethingTwice(sayHello);
[sayHello release];
return 0;
使用选择器的示例:
@interface SaySomething : NSObject
- (void) sayHello;
@end
@implementation SaySomething
- (void) sayHello
NSLog(@"Hello!");
@end
void doSomethingTwice(id<NSObject> obj, SEL selector)
[obj performSelector:selector];
[obj performSelector:selector];
int main(void)
SaySomething* saySomething = [[SaySomething alloc] init];
doSomethingTwice(saySomething, @selector(sayHello));
[saySomething release];
return 0;
【讨论】:
这在之前可能是正确的,但该语言现在确实有块,它允许您定义真正的 lambda 表达式。话虽如此,如上所述,能够传递 @selector()s 是 Objective-C 工具包中非常有用的机制。 -1 用于在新的 10.6 版 OS X 中使用 Apple 的 GCC 时缺少有关块的信息,这是 C、ObjC 和 C++ 中可用的一项核心新功能。 +1 用于提供在某些情况下可能比块更可取的设计模式。【参考方案3】:我在 NSConference 上听到 André Pang 谈到下一个版本的 Objective-C 将如何引入块。
这应该允许函数式编程。
编辑:自从雪豹发布以来,确实如此。 Objective-C 现在有Blocks。
【讨论】:
以上是关于如何在 Objective-C 中编写 lambda 方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 插件的 Swift 编写的 iOS 部分中使用 Objective-C 框架
如何/在哪里声明用于编写objective-c代码的接口、实现、程序格式中的实例变量?
如何在 Objective-C 控制器中以编程方式加载用 swift 编写的自定义 XIB 视图
如何将 watchOS Swift 目标添加到用 Objective-C 编写的 iOS 应用程序中