Add closure to extension within swift in runtime
2015-11-19 22:44
591 查看
Add closure to extension within swift
主要是利用objc_setAssociatedObject将closure添加到实例中去,先看看该方法在
Objective-c和
swift中的声明:
Objective-C
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
swift:
public func objc_setAssociatedObject(object: AnyObject!, _ key: UnsafePointer<Void>, _ value: AnyObject!, _ policy: objc_AssociationPolicy)
主要是参数
value的类型,分别是
id和
AnyObject,在
Objective-C中,系统会自动将Block转化
id类型,正常使用,而在
swift里则会提示形如下面的错误信息:
实例代码:
typealias TestClosureType = ()->() var testClosure: TestClosureType objc_setAssociatedObject(self, "Test Block", testClosure, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
错误信息提示如下:
Cannot convert value of type 'TestClosureType' (aka '()->()') to expected argument type 'AnyObject!'
原因很清晰,类型不符合,只需要将closure转成AnyObject类型即可,借助于:
public func unsafeBitCast<T, U>(x: T, _: U.Type) -> U
可以将 closure转成
AnyObject类型,只是我们还需要修改点东西,修改之后的结果如下:
typealias TestClosureType = @convention(block)()->() var testClosure: TestClosureType objc_setAssociatedObject(self, "Test Block", unsafeBitCast(testClosure, AnyObject.self), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
取出来的时候再转回去,方法如下:
let completionBlock = unsafeBitCast(objc_getAssociatedObject(self, "Test Block"), TestClosureType.self)
使用这个方法,主要是想偷懒,当然定义代理啊通知啊等等都可以解决问题,另当别论。
参考:Cast Closures/Blocks
相关文章推荐
- 深入理解PHP之匿名函数
- Apple Swift学习教程
- LUA中的闭包(closure)浅析
- javascript prototype,executing,context,closure
- JavaScript中的闭包(Closure)详细介绍
- javascript 必知必会之closure
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
- Swift编程中的泛型解析
- Swift中定义二维数组的方法及遍历方法示例
- 浅谈PHP Extension的开发――基础篇第1/2页
- Lua学习笔记之函数、变长参数、closure(闭包)、select等
- PHP中Closure类的使用方法及详解
- Javascript闭包(Closure)详解
- php的闭包(Closure)匿名函数详解
- 简单分析Swift语言的一些基本特征
- Swift与C语言指针结合使用实例
- Swift心得笔记之控制流
- 用Swift构建一个简单的iOS邮件应用的方法
- 苹果公司推出的新编程语言Swift简介和入门教程