大佬教程收集整理的这篇文章主要介绍了ios – 方法Swizzling不起作用,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
给定两个方法A和B,我想交换它们的实现,这样调用A就会执行B.我偶然发现了一些混合的例子(example1和example2).我创建了一个带有类的新项目来测试它.@H_404_3@
class Swizzle: NSObject { func method() { print("A"); } } extension Swizzle { override class func initialize() { struct Static { static var token: dispatch_once_t = 0; } // make sure this isn't a subclass if (self !== Swizzle.self) { return; } dispatch_once(&Static.token) { let originalSELEctor = SELEctor("method"); let swizzledSELEctor = SELEctor("methodExt"); let originalMethod = class_geTinstanceMethod(self,originalSELEctor); let swizzledMethod = class_geTinstanceMethod(self,swizzledSELEctor); print(method_getImplementation(originalMethod)); print(method_getImplementation(swizzledMethod)); let didAddMethod = class_addMethod(self,originalSELEctor,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod)); if DidAddMethod { class_replaceMethod(self,swizzledSELEctor,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod,swizzledMethod); } print(method_getImplementation(originalMethod)); print(method_getImplementation(swizzledMethod)); } } func methodExt() { print("B"); } }
然后我尝试用它来执行它@H_404_3@
var s = Swizzle(); s.method();
预期输出为“B”,但仍然打印“A”.从我的代码中可以看出,我在swizzle操作之前和之后都包含了每个IMP的打印件.这些打印显示交换确实发生,但输出保持不变.@H_404_3@
0x000000010251a920 0x000000010251ad40 0x000000010251ad40 0x000000010251a920 A
class Swizzle: NSObject { dynamic func method() { print("A") } }
在Swift中使用方法调配时,您的类/方法必须符合以下两个要求:@H_404_3@
>您的课程必须扩展NSObject
>您想要调配的函数必须具有动态属性@H_404_3@
有关为何需要此操作的完整说明,请查看Using Swift with Cocoa and Objective-C:@H_404_3@
Swift 3更新:@H_404_3@
关于GCD已经有一些变化,并且dispatch_once不再可用.为了执行相同的一次操作,我们可以将代码包含在全局静态类常量的初始化块中.@H_404_3@
Swift语言保证此代码在应用程序的生命周期内仅执行一次.@H_404_3@
class TestSwizzling : NSObject { dynamic func methodOne()->Int{ return 1 } } extension TestSwizzling { //In Objective-C you'd perform the swizzling in load(),//but this method is not permitted in Swift override class func initialize() { struct Inner { static let i: () = { let originalSELEctor = #SELEctor(TestSwizzling.methodOnE) let swizzledSELEctor = #SELEctor(TestSwizzling.methodTwo) let originalMethod = class_geTinstanceMethod(TestSwizzling.self,originalSELEctor); let swizzledMethod = class_geTinstanceMethod(TestSwizzling.self,swizzledSELEctor) method_exchangeImplementations(originalMethod,swizzledMethod) } } let _ = Inner.i } func methodTwo()->Int{ // It will not be a recursive call anymore after the swizzling return methodTwo()+1 } } var c = TestSwizzling() print(c.methodOne()) print(c.methodTwo())
Swift 2.2更新:@H_404_3@
我已经为新的#SELEctor属性更新了原始示例:@H_404_3@
class TestSwizzling : NSObject { dynamic func methodOne()->Int{ return 1 } } extension TestSwizzling { //In Objective-C you'd perform the swizzling in load(),//but this method is not permitted in Swift override class func initialize() { struct Static { static var token: dispatch_once_t = 0 } // Perform this one time only dispatch_once(&Static.token) { let originalSELEctor = #SELEctor(TestSwizzling.methodOnE) let swizzledSELEctor = #SELEctor(TestSwizzling.methodTwo) let originalMethod = class_geTinstanceMethod(self,originalSELEctor); let swizzledMethod = class_geTinstanceMethod(self,swizzledMethod) } } func methodTwo()->Int{ // It will not be a recursive call anymore after the swizzling return methodTwo()+1 } } var c = TestSwizzling() print(c.methodOne()) print(c.methodTwo())
以上是大佬教程为你收集整理的ios – 方法Swizzling不起作用全部内容,希望文章能够帮你解决ios – 方法Swizzling不起作用所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。