swift的@convention

我們經(jīng)常將一個函數(shù)作為參數(shù)傳入另一個函數(shù)。
那么在iOS上能作為一個函數(shù)參數(shù)的東西有哪些呢

  1. c的函數(shù)指針
  2. oc的block
  3. swift的閉包(closures)

ok回歸正題,先說下@convention是干什么的。
他是用來修飾閉包的。他后面需要跟一個參數(shù):

  1. @convention(swift) : 表明這個是一個swift的閉包
  2. @convention(block) :表明這個是一個兼容oc的block的閉包
  3. @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ù)之后, 祝大家新年快樂
 
*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容