我們經(jīng)常將一個函數(shù)作為參數(shù)傳入另一個函數(shù)。
那么在iOS上能作為一個函數(shù)參數(shù)的東西有哪些呢
- c的函數(shù)指針
- oc的block
- swift的閉包(closures)
ok回歸正題,先說下@convention是干什么的。
他是用來修飾閉包的。他后面需要跟一個參數(shù):
- @convention(swift) : 表明這個是一個swift的閉包
- @convention(block) :表明這個是一個兼容oc的block的閉包
- @convention(c) : 表明這個是兼容c的函數(shù)指針的閉包。
class Person:NSObject {
func doAction(action: @convention(swift) (String)->Void, arg:String){
action(arg)
}
}
let saySomething_c : @convention(c) (String)->Void = {
print("i said: \($0)")
}
let saySomething_oc : @convention(block) (String)->Void = {
print("i said: \($0)")
}
let saySomething_swift : @convention(swift) (String)->Void = {
print("i said: \($0)")
}
let person = Person()
person.doAction(action: saySomething_c, arg: "helloworld")
person.doAction(action: saySomething_oc, arg: "helloworld")
person.doAction(action: saySomething_swift, arg: "helloworld")
為啥今天要寫這個呢?因為我在用runtime的imp_implementationWithBlock這個函數(shù)時不知道咋傳參數(shù)。我用swift的閉包怎么都不對,看完@convention之后就知道該怎么辦了。
class Person:NSObject {
//數(shù) 數(shù)字
dynamic func countNumber(toValue:Int){
for value in 0...toValue{
print(value)
}
}
}
//現(xiàn)在我們要替換數(shù)數(shù)函數(shù)的實現(xiàn),給他之前和之后加上點廣告語。
//拿到method
let methond = class_getInstanceMethod(Person.self, #selector(Person.countNumber(toValue:)))
//通過method拿到imp, imp實際上就是一個函數(shù)指針
let oldImp = method_getImplementation(methond!)
//由于IMP是函數(shù)指針,所以接收時需要指定@convention(c)
typealias Imp = @convention(c) (Person,Selector,NSNumber)->Void
//將函數(shù)指針強轉(zhuǎn)為兼容函數(shù)指針的閉包
let oldImpBlock = unsafeBitCast(oldImp!, to: Imp.self)
//imp_implementationWithBlock的參數(shù)需要的是一個oc的block,所以需要指定convention(block)
let newFunc:@convention(block) (Person, NSNumber)->Void = {
(sself, toValue) in
print("數(shù)之前, 祝大家新年快樂")
oldImpBlock(sself, #selector(Person.countNumber(toValue:)), toValue)
print("數(shù)之后, 祝大家新年快樂")
}
let imp = imp_implementationWithBlock(unsafeBitCast(newFunc, to: AnyObject.self))
method_setImplementation(methond!, imp)
let person = Person()
person.countNumber(toValue: 50)
/**
輸出將是
數(shù)之前, 祝大家新年快樂
0
1
3
。。。
。。。
49
50
數(shù)之后, 祝大家新年快樂
*/