Add closure to extension within swift in runtime

原创 2015年11月19日 22:44:19

Add closure to extension within swift

主要是利用objc_setAssociatedObject将closure添加到实例中去,先看看该方法在Objective-cswift中的声明:

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的类型,分别是idAnyObject,在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

安装tensorflow,那叫一个坑啊

转自 http://www.cnblogs.com/shihuc/p/6593041.html 最近,项目团队需要研究并应用AI的技术,在具体的产品实施环节中使用。之前的几个项目...
  • ada_1215
  • ada_1215
  • 2017年05月21日 22:24
  • 1872

Maven用仓库外的jar进行编译

http://blog.csdn.net/zhouysh/article/details/5713532   之所以采用Maven调用ant 进行编译,是因为有一些lib 并不在远程仓库里,而是直...
  • caolaosanahnu
  • caolaosanahnu
  • 2013年01月31日 17:11
  • 2537

第一个 Gradle 脚本及简单命令

第一个 Gradle 脚本及简单命令task helloworld { doLast { print 'Hello world!' } } /* ...
  • u012885276
  • u012885276
  • 2017年03月10日 17:14
  • 2005

Pods written in Swift can only be integrated as frameworks; add `use_frameworks!` to your Podfile or

在使用cocoapod导入swift第三方时出现这样的问题: Pods written in Swift can only be integrated as frameworks; add use_...
  • zww1984774346
  • zww1984774346
  • 2016年04月28日 18:47
  • 6956

How To Turn Up Logging on the Siebel Web Server Extension in Siebel Versions 7.x and 8.x? [ID 477185

How To Turn Up Logging on the Siebel Web Server Extension in Siebel Versions 7.x and 8.x? [ID 477185...
  • lixiaohuiok111
  • lixiaohuiok111
  • 2012年04月23日 14:25
  • 2214

An add-in to automatically increment the PrivateBuild field

  • 2006年02月23日 09:05
  • 34KB
  • 下载

In this step we add a simple COM object to our server using

  • 2006年02月23日 09:05
  • 24KB
  • 下载

An add-in and standalone EXE to create your badly needed com

  • 2006年02月23日 09:05
  • 68KB
  • 下载

How to Add a New Protocol in NS2(如何创建新的协议)

  • 2011年06月30日 11:12
  • 399KB
  • 下载

Leetcode--Add to List 215. Kth Largest Element in an Array

题目Find the kth largest element in an unsorted array. Note that it is the kth largest element in the ...
  • wanna_wsl
  • wanna_wsl
  • 2017年07月03日 11:05
  • 139
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Add closure to extension within swift in runtime
举报原因:
原因补充:

(最多只允许输入30个字)