gpt4 book ai didi

swift - NSLocale 使用方法 swizzling 更改 currentLocale 输出以进行测试

转载 作者:可可西里 更新时间:2023-11-01 00:59:48 32 4
gpt4 key购买 nike

我正在尝试更改设备 currentLocale 输出以执行一些有趣的单元测试,这是我正在使用的代码,但返回的 currentLocale 似乎没有被覆盖。有什么提示吗?

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_addMethod 有什么问题?

最佳答案

您的第一个方法对于调配实例方法是正确的,但不适用于类方法。如果我理解正确的话,会发生什么?

let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

向类添加一个实例方法,并返回true。然后

 class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))

替换失败的实例方法

如果您查看 Method Swizzling 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_addMethod() 在类对象上调用,而不是在 self 上调用。)

但实际上我看不出比你的第二种方法有任何优势。didAddMethod 将始终返回 false 因为 frLocale已经定义为 NSLocale 的类方法。

关于swift - NSLocale 使用方法 swizzling 更改 currentLocale 输出以进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36498542/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com