[swift学习之十六]RunTime练习一

来源:互联网 发布:矩阵乘法计算公式 编辑:程序博客网 时间:2024/04/30 16:04
/* 1:如果不继承NSObject的话,不能获取objc_property_t和Method的信息。看来要想用好runtime,必须继承NSObject啊~! */class RunTimeTest:NSObject{    override class func description() -> String {        return "RunTimeTest"    }    static var StaticProperty = 0    var StorePropertyStr = "Hello"    var StoreProperty = 1    var CaculateProperty: Int{        get{           return StoreProperty        }        set(newValue){            StoreProperty = newValue        }    }    dynamic func TestMethondFirst() -> Void {        print("\(#function)")    }    dynamic func TestMethondSecond() -> Void {        print("\(#function)")    }}/*获取父类名,如果不继承NSObject的话,是swiftobject*/if class_getSuperclass(RunTimeTest) == NSObject.classForCoder() {    print("父类是NSObject")}/*获取实例的大小,不受静态变量的限制。空类是16字节,self应该占8字节,另外的就不知道了。~*/print("RunTimeTest的实例大小:\(class_getInstanceSize(RunTimeTest))")/*获取类型 通过class_getName这个方式获得的类型串,前面有个前缀__lldb_expr_1472,不明白啥意思啊~! 但是RunTimeTest.classForCoder().description()也是一样,看来得改下description了。*/RunTimeTest.classForCoder().description()RunTimeTest.selfprint(String.fromCString(class_getName(RunTimeTest))!)/*设置版本,读取版本,不设置的话是0,但不知道这个有什么用~~!*/class_getVersion(RunTimeTest)//0RunTimeTest.setVersion(8)class_getVersion(RunTimeTest)//8/*获取元类*/objc_getMetaClass(class_getName(RunTimeTest.self))/*获取全部成员变量信息*/var iVarCount: UInt32 = 0let ivarArr:UnsafeMutablePointer<Ivar> = class_copyIvarList(RunTimeTest.self, &iVarCount)var CurrIvar:UnsafeMutablePointer<Ivar> = ivarArrfor _ in 1...iVarCount{    ivar_getOffset(CurrIvar.memory)    print(String.fromCString(ivar_getName(CurrIvar.memory)))    CurrIvar = ivarArr.successor()}/*获取全部属性信息,注意,这里包括计算属性和存储属性。 property_getAttributes 的结果是“T@\\"NSString\\",N,C,VStorePropertyStr” 没读懂这个信息的具体含义~*/let PropArr:UnsafeMutablePointer<objc_property_t> = class_copyPropertyList(RunTimeTest.self, &iVarCount)var CurrProp:UnsafeMutablePointer<objc_property_t> = PropArrfor _ in 1...iVarCount{    print(String.fromCString(property_getName(CurrProp.memory)))    print(String.fromCString(property_getAttributes(CurrProp.memory)))    CurrProp = PropArr.successor()}/*获取全部的方法信息*/let MethodArr:UnsafeMutablePointer<Method> = class_copyMethodList(RunTimeTest.self, &iVarCount)var CurrMethod:UnsafeMutablePointer<Method> = MethodArrfor _ in 1...iVarCount{    print(NSStringFromSelector(method_getName(CurrMethod.memory)))    let MethodType = method_getDescription(CurrMethod.memory).memory.types    print(String.fromCString(MethodType))    /*这个地方居然能运行,而且还能得到正确的方法签名MethodType,不可思议啊~!*/    print(String.fromCString(property_getAttributes(CurrMethod.memory)))    CurrMethod = CurrMethod.successor()}/*上面的三个循环的结果如下,protocol的就不试验了,过程都一样~! -----成员变量------ Optional("StorePropertyStr") Optional("StoreProperty") -----全部属性------ Optional("StorePropertyStr") Optional("T@\"NSString\",N,C,VStorePropertyStr") Optional("StoreProperty") Optional("Tq,N,VStoreProperty") Optional("StoreProperty") Optional("Tq,N,VStoreProperty") -----全部方法------ StorePropertyStr Optional("@16@0:8") setStorePropertyStr: Optional("v24@0:8@16") StoreProperty Optional("q16@0:8") setStoreProperty: Optional("v24@0:8q16") CaculateProperty Optional("q16@0:8") setCaculateProperty: Optional("v24@0:8q16") .cxx_destruct Optional("@?") init Optional("@16@0:8") *//*实例部分*/let InstanceRun = RunTimeTest()/*获取类型信息*/objc_getClass(class_getName(RunTimeTest))InstanceRun.classForCoder.description()/*获取某一存储属性信息,COpaquePointer这个玩意就是void*吧~! 1,这里指针对存储属性,计算属性为nil。 2,ivar_getOffset偏移字节数,空类为16字节,不受计算属性及函数影响。*/let iVarPro:Ivar = class_getInstanceVariable(InstanceRun.classForCoder, "StorePropertyStr")print(String.fromCString(ivar_getName(iVarPro)))ivar_getOffset(iVarPro)/*获取类中实例的方法*/let SecondMethod = class_getInstanceMethod(RunTimeTest.self, NSSelectorFromString("TestMethondSecond"))/*获取类中实例的方法的指针*/let ImpSecond =  method_getImplementation(SecondMethod)/*和下面等价*///let ImpSecond = class_getMethodImplementation(InstanceRun.classForCoder, NSSelectorFromString("TestMethondSecond"))/*替代原有方法*/class_replaceMethod(InstanceRun.classForCoder, NSSelectorFromString("TestMethondFirst"), ImpSecond, method_getDescription(SecondMethod).memory.types)/* 1,这里被替换的函数必须是dynamic的,否则没有效果,找半天才找到~! 2,下面一段话,是讲的为什么dynamic的函数才能实现动态替换,没怎么看明白~~! 方法调配是替换一个已存在的方法实现。Swift优化后,不再像Objective-C中那样,在runtime寻找方法的位置,而是直接调用内存地址。因此默认情况下,在Swift类中调配无法起效,除非: 用动态关键字禁用这种优化。这是最佳选择,如果数据库完全以Swift构建的话,这种选择也是最合理的方式。 扩展NSObject。如果单纯为了方法调配的话,不要用这种方式(而要采用动态的)。需要了解:在将NSObject作为基础类的已存在类中,方法调配是有效的,不过最好使用动态选择的方法。 在要调配的方法中使用@objc注释。如果我们想要调配的方法同时也需要使用Objective-C的代码,那么这种方法是最合适的 3,通过Swift执行方法调用要比使用Objective-C快四倍。*/InstanceRun.TestMethondFirst()//结果:TestMethondSecond()

还有其他内容没有练习,如动态创建类,添加方法等。下一篇继续。

参考:http://blog.jobbole.com/79566/

          http://www.tuicool.com/articles/ArYbuaJ

0 0
原创粉丝点击