【发布时间】:2020-05-16 14:23:40
【问题描述】:
鉴于应用程序使用的 ObjC 中的这段代码,我想将其转换为 Swift:
typedef void (^VoidBlock)(void);
@interface Worker : NSObject
- (void)add:(VoidBlock)completion;
- (void)remove:(VoidBlock)completion;
- (void)execute;
@end
@implementation Worker {
NSMutableArray<VoidBlock> *completions;
}
- (void)add:(VoidBlock)completion {
[completions addObject:completion];
}
- (void)remove:(VoidBlock)completion {
[completions removeObject:completion];
}
- (void)execute {
// ...
[completions enumerateObjectsUsingBlock:^(VoidBlock _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj();
}];
}
@end
我在实施移除时遇到问题。我尝试了几件事,但没有。基本上,我无法比较 Swift 中的闭包,因为显然闭包不符合 Equatable 协议,因此无法在数组中找到它。或许内存地址可以用来做这个,不知道是不是objc指针和swift引用有问题。理论上,这段代码可以从 objc 或 swift 中使用。我的另一个想法是使用类似的东西:
let firstIndex = hardWorkers.firstIndex(where:{
$0 === hardWorkerClosure
})
请注意身份运算符,但这不起作用。一位朋友告诉我,也许我必须使用容器来关闭/阻塞。我记得在 Objc 中,我们有 NSValue 将原始类型包装在一个类中,因此,我们可以将它们保存在 NSMutableArray 中,但我不记得有任何保存块的东西。您对如何解决此问题有任何想法或建议吗?非常感谢。
【问题讨论】:
-
您能否展示一下您从 Objective-C 成功转换的 Swift 代码部分?
-
闭包没有可比性,也没有定义的标识,以便给编译器更多的发挥空间,优化和合并闭包实现。如果您需要将身份与闭包相关联,您需要自己执行此操作:stackoverflow.com/a/45284442/3141234
-
@Ricardo 在 ObjC 中,块通常由它们的地址处理。您将指向它们的指针传递给 ARC(如果您使用手动内存管理)、复制它们等。在 Swift 中,它们有意不将闭包标识暴露给“用户空间”Swift 代码.动机在这里:stackoverflow.com/a/25694072/3141234
-
Swift 闭包也不仅仅是一个指针:forums.swift.org/t/…
标签: objective-c swift