Swift NSLocale使用方法swizzling更改当前语言环境输出以进行测试
我试图更改设备currentLocale输出以执行一些有趣的单元测试,这是我正在使用的代码,但返回的currentLocale似乎没有被覆盖。有什么提示吗Swift NSLocale使用方法swizzling更改当前语言环境输出以进行测试,swift,testing,swizzling,Swift,Testing,Swizzling,我试图更改设备currentLocale输出以执行一些有趣的单元测试,这是我正在使用的代码,但返回的currentLocale似乎没有被覆盖。有什么提示吗 extension NSLocale { class func frLocale()->NSLocale{ return NSLocale(localeIdentifier: "fr_FR") } class func forceCurrentLocale(){ let orig
extension NSLocale {
class func frLocale()->NSLocale{
return NSLocale(localeIdentifier: "fr_FR")
}
class func forceCurrentLocale(){
let originalSelector = #selector(NSLocale.currentLocale)
let swizzledSelector = #selector(self.frLocale)
let originalMethod = class_getClassMethod(self, originalSelector)
let swizzledMethod = class_getClassMethod(self, swizzledSelector)
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)
}
}
}
//编辑
上面的代码不起作用。但如果我这样写的话,它会起作用:
class func forceCurrentLocale(){
let originalSelector = #selector(NSLocale.currentLocale)
let swizzledSelector = #selector(NSLocale.frLocale)
let originalMethod = class_getClassMethod(self, originalSelector)
let swizzledMethod = class_getClassMethod(self, swizzledSelector)
method_exchangeImplementations(originalMethod, swizzledMethod)
}
在这种情况下,
class\u addMethod
有什么问题?您的第一个方法可以正确地使用实例方法,
但不是针对类方法。
如果我理解正确的话,会发生什么
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
将实例方法添加到类中,并返回true
。然后
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
替换失败的实例方法
如果您阅读NSHipster的文章,您会发现以下评论:
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(class, originalSelector);
// Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
翻译成Swift就是
class func forceCurrentLocale(){
let originalSelector = #selector(NSLocale.currentLocale)
let swizzledSelector = #selector(self.frLocale)
let classObject : AnyClass = object_getClass(self)
let originalMethod = class_getClassMethod(classObject, originalSelector)
let swizzledMethod = class_getClassMethod(classObject, swizzledSelector)
let didAddMethod = class_addMethod(classObject, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
然后,swizzling按预期工作。(关键是
class\u addMethod()
在类对象上调用,而不是在self
上调用)
但事实上,我看不出比你的第二种方法有什么优势。
didAddMethod
将始终返回false
,因为frLocale
已定义为NSLocale
的类方法