Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift NSLocale使用方法swizzling更改当前语言环境输出以进行测试_Swift_Testing_Swizzling - Fatal编程技术网

Swift NSLocale使用方法swizzling更改当前语言环境输出以进行测试

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

我试图更改设备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\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
的类方法