如何将此 Objective-C 块存储在 Swift 变量中?
How to store this Objective-C block inside a Swift variable?
这是 Objective-C 块:
@property (copy) void (^anObjcBlock)();
anObjcBlock = ^{
NSLog(@"Yea man this thing works!!");
};
NSMutableArray *theArrayThatHasTheBlockInItAtIndexZero = [NSMutableArray array];
[theArrayThatHasTheBlockInItAtIndexZero addObject:anObjBlock];
这是我在 Swift 中所做的:
var theBlock: (()->Void)?
theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as? ()->Void
// Now call the block
theBlock!()
但是我得到运行时错误。
基本上,theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as? ()->Void
语句会使 theBlock
为零,因为 as?
失败了。当我将语句更改为 theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as! ()->Void
时,出现运行时错误:
我不知道还能做什么。这是一个空项目,里面真的没有代码。
在本例中,问题似乎来自 NSMutableArray。
[NSMutableArray objectAtIndex:] returns id in Objective-C,它被翻译成 AnyObject 来自 Swift.
如果您尝试将 AnyObject 转换为 () ->Void.
,您将收到错误消息
解决方法如下:
// Create your own typealias (we need this for unsafeBitcast)
typealias MyType = @convention(block) () -> Void
// Get the Obj-C block as AnyObject
let objcBlock : AnyObject = array.firstObject! // or [0]
// Bitcast the AnyObject Objective-C block to a "Swifty" Objective-C block (@convention(block))
// and then assign the result to a variable of () -> Void type
let block : () -> Void = unsafeBitCast(objcBlock, MyType.self)
// Call the block
block()
这段代码对我有用。
有趣的事实
如果您将 Objective-C 代码编辑为如下所示...
// Typedef your block type
typedef void (^MyType)();
// Declare your property as NSArray of type MyType
@property (strong) NSArray<MyType>* array;
Swift 现在会将数组类型报告为 [MyType]!.
出于某种原因,NSMutableArray 上的泛型似乎没有被 Swift 接受。
尽管如此,如果您执行以下命令,您将遇到运行时错误:
let block : MyType? = array[0]
这是 Objective-C 块:
@property (copy) void (^anObjcBlock)();
anObjcBlock = ^{
NSLog(@"Yea man this thing works!!");
};
NSMutableArray *theArrayThatHasTheBlockInItAtIndexZero = [NSMutableArray array];
[theArrayThatHasTheBlockInItAtIndexZero addObject:anObjBlock];
这是我在 Swift 中所做的:
var theBlock: (()->Void)?
theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as? ()->Void
// Now call the block
theBlock!()
但是我得到运行时错误。
基本上,theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as? ()->Void
语句会使 theBlock
为零,因为 as?
失败了。当我将语句更改为 theBlock = theArrayThatHasTheBlockInItAtIndexZero[0] as! ()->Void
时,出现运行时错误:
我不知道还能做什么。这是一个空项目,里面真的没有代码。
在本例中,问题似乎来自 NSMutableArray。
[NSMutableArray objectAtIndex:] returns id in Objective-C,它被翻译成 AnyObject 来自 Swift.
如果您尝试将 AnyObject 转换为 () ->Void.
,您将收到错误消息解决方法如下:
// Create your own typealias (we need this for unsafeBitcast)
typealias MyType = @convention(block) () -> Void
// Get the Obj-C block as AnyObject
let objcBlock : AnyObject = array.firstObject! // or [0]
// Bitcast the AnyObject Objective-C block to a "Swifty" Objective-C block (@convention(block))
// and then assign the result to a variable of () -> Void type
let block : () -> Void = unsafeBitCast(objcBlock, MyType.self)
// Call the block
block()
这段代码对我有用。
有趣的事实
如果您将 Objective-C 代码编辑为如下所示...
// Typedef your block type
typedef void (^MyType)();
// Declare your property as NSArray of type MyType
@property (strong) NSArray<MyType>* array;
Swift 现在会将数组类型报告为 [MyType]!.
出于某种原因,NSMutableArray 上的泛型似乎没有被 Swift 接受。
尽管如此,如果您执行以下命令,您将遇到运行时错误:
let block : MyType? = array[0]