2016-04-08 17 views
2

Bazı ilginç birim testlerini gerçekleştirmek için cihazın currentLocale çıkışını değiştirmeye çalışıyorum, bu benim kullandığım koddur, ancak dönen currentLocale'ın yaptığı gibi görünüyor. Devrilme. Herhangi bir ipucu?NSLocale, test amaçları için currentLocale çıkışını değiştirmek için swizzling kullanarak

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) 
     } 
    } 
} 

// DÜZENLEME

Yukarıdaki kod çalışmaz. Ben böyle yazarsanız Ama çalışır: bu durumda class_addMethod nesi

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) 
} 

?

cevap

3

İlk yönteminiz, bir örnek yöntemi, , ancak bir sınıf yöntemi için değil, doğru bir şekilde yürütülür. Ben doğru anlamak eğer - - ne olur

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

sınıfa bir örnek yöntemi eklediği ve true döndürür. Daha sonra

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

başarısız bir örnek yöntemi, yerine geçer.

// 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 dile çevrildi

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) 
    } 
} 

olması ve beklendiği gibi daha sonra swizzling çalışır olacaktır: Eğer NSHipster dan Method Swizzling maddeye bakarsak

o zaman şu yorumu bulacaksınız. (Önemli olan nokta, self'da değil, sınıf nesnesinde class_addMethod()'un çağrılmasıdır.)

Ancak, ikinci yönteme göre bir avantaj görmüyorum. didAddMethod her zaman false dönecektir, çünkü frLocale zaten NSLocale sınıf yöntemi olarak tanımlanmıştır.

İlgili konular