Ios 用静态字符串快速旋转
我试图swizzle一个包含StaticString参数的Swift函数 以下是我尝试过的:Ios 用静态字符串快速旋转,ios,swift,method-swizzling,Ios,Swift,Method Swizzling,我试图swizzle一个包含StaticString参数的Swift函数 以下是我尝试过的: let method = class_getClassMethod(self, original1) class ABC { public static func updateABC(context: Int, str: StaticString) { } } 但是,这不起作用,如果我将str的类型更改为String,我们可以正确地swizzle,任何有机会使用StaticString类型参
let method = class_getClassMethod(self, original1)
class ABC {
public static func updateABC(context: Int, str: StaticString) {
}
}
但是,这不起作用,如果我将str的类型更改为String,我们可以正确地swizzle,任何有机会使用StaticString类型参数swizzle函数的人都可以帮忙吗
感谢您,StaticString是一种值类型,因此它没有Objective-C表示形式。因此,它——以及您在其中使用它的声明——不会向Objective-C代码公开,也不会向Objective-C运行时注册<另一方面,code>String与Objective-C兼容(它连接到
NSString
),因此声明与Objective-C兼容
如果您要swizzle一个方法,您需要用
dynamic
标记它,让编译器知道它应该始终通过Objective-C运行时路由调用,即使在优化的代码中也是如此。如果您的函数与Objective-C不兼容,则将函数标记为dynamic
也会导致编译器发出错误,这可以帮助您诊断问题。为什么要这样做?例如-Swizzle swift的assertFailure@BryanChenso下一个问题是。。。为什么需要swizzleassertFailure
?难道你不能用一个方法myAssertFailure
来代替调用它吗?方法swizzle是ObjC独有的,我认为您不应该将其用于Swift项目,因为它不会总是像您期望的那样工作。Swift编译器可能会进行积极的内联,这将选择原始的实现,而不是swizzled的实现。我同意@BryanChen的观点。Swift是安全的,即使在Swift 2中,反射功能也是只读的(应该是只读的)。使用obj-c运行时在Swift中执行任何类型的swizzling都是一个坏主意;并非每种类型都支持它(原生swift类型,如structs、enum等),我本人来自Objective-C,但我仍然发现编写swift代码需要改变对如何设计类、结构等的思考。虽然有一些情况需要进行动态内省,但有很多理由不这样做。我甚至可以说,在Objective-C中可以完成的一切都可以在Swift中完成,这只是一个如何设计类的问题。以ReactiveCocoa为例,它主要依靠KVO来观察Swift所没有的变化。现在他们有了一个新的机制,属性上的可变和不可变包装。谢谢!这是有道理的。因此,当您声明声明没有在Objc运行时注册时,该函数如何工作,比如C++ VTABLE查找?还有其他Swift/Objc方法不绑定到Objc运行时的情况吗?@OliverHu问得好。有几种不同的方法可以进行Swift方法分派,这取决于编译器/优化器来决定(除非您使用动态
)。例如,在某些情况下,它类似于vtable,在其他情况下,优化器可能直接内联该方法的实现。所有swift结构和枚举都使用静态分派。对于纯swift类–不从任何Objective-C类继承的swift类–编译器也可以选择不向Objective-C运行时注册该类。