如何在swift变量中存储这个objectiveC块?

时间:2015-09-25 06:46:19

标签: objective-c swift cocoa cocoa-touch objective-c-blocks

这是objectiveC块

@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时,我得到运行时错误enter image description here

我不确定还能做什么。这是一个空项目,其中确实没有代码。

1 个答案:

答案 0 :(得分:4)

在这种情况下,问题似乎来自 NSMutableArray

[NSMutableArray objectAtIndex:] 在Objective-C中返回 id ,由Swift转换为 AnyObject

如果您尝试将 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()

此代码适用于我。

FUNNY FACT

如果您编辑Objective-C代码看起来像这样......

//Typedef your block type
typedef void (^MyType)();

//Declare your property as NSArray of type MyType
@property (strong) NSArray<MyType>* array;

Swift现在将数组类型报告为 [MyType]!

出于某种原因,Swift似乎没有接收到 NSMutableArray 上的泛型。

尽管如此,如果执行:

,您将收到运行时错误
 let block : MyType? = array[0]