如何在swift 2.3中使用#undef指令

如何在swift 2.3中使用#undef指令,swift,localization,preprocessor-directive,nslocalizedstring,xcode8.1,Swift,Localization,Preprocessor Directive,Nslocalizedstring,Xcode8.1,我想在swift 2.3中取消定义或覆盖NSLocalizedString,我对此进行了大量搜索,最后在目标C中找到了一种方法,如下所示 #undef NSLocalizedString #define NSLocalizedString(key,_comment) your_function_name 我想用swift实现这个功能。 我只知道NSLocalizedString是目标C的NSBundle.h中的一个宏。因此我们可以重新定义它。但对于swift我们无法实现这一点。我只想为swif

我想在swift 2.3中取消定义或覆盖
NSLocalizedString
,我对此进行了大量搜索,最后在目标C中找到了一种方法,如下所示

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) your_function_name
我想用swift实现这个功能。 我只知道
NSLocalizedString
是目标C的
NSBundle.h
中的一个宏。因此我们可以重新定义它。但对于swift我们无法实现这一点。我只想为swift重新定义或覆盖NSLocalizedString函数。请帮我解决这个问题。如果有任何帮助,我们将不胜感激。

\undef
是一个,swift,包括用于
NSLocalizedString
的复杂
#define
宏。事实上,它的输入方式是:

/// Returns a localized string, using the main bundle if one is not specified.
public func NSLocalizedString(_ key: String, tableName: String? = default, bundle: Bundle = default, value: String = default, comment: String) -> String
但是,您只需编写自己的实现就可以轻松完成预期的行为,而应该自动使用它例如

public func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String {
    // Do your magic here!
    return "test"
}

但请不要这样做。创建一个不同的函数会更好。否则,将无法确定您的函数是否是正在使用的函数,或者您可能会得到:
错误:如果您需要更改签名,即使您只是想做一些可选的事情,也可能会模糊地使用“NSLocalizedString(uu2;:tableName:bundle:value:comment:)
。NSLocalizedString是Swift中的全局方法

不能重写全局函数,但可以重新定义它。要重新定义该方法,只需声明一个新版本。所选功能将基于范围。例如:

func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String {
    return "redefined version in the project"
}

class Test {
    func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String {
        return "redefined version in Test"
    }

    func getLocalizedString() -> String{
        return NSLocalizedString("test", comment: "t")
    }
}

class Test2 {
    func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String {
        return "redefined version in Test2"
    }

    func getLocalizedString() -> String{
        return NSLocalizedString("test", comment: "t")
    }
}

NSLocalizedString("test", comment: "t") //will return "redefined version in the project"
Test().getLocalizedString() //will return "redefined version in Test"
Test2().getLocalizedString() //will return "redefined version in Test2"
如果您在副类中使用NSLocalizedString,那么它只会对您有所帮助。 在swift 4上对其进行了以下调整

extension NSObject {
    func NSLocalizedString(_ key: String, comment: String) -> String {
        return "My custom localization"
    }

    static func NSLocalizedString(_ key: String, comment: String) -> String {
        return "My custom localization"
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var myLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        myLabel.text = NSLocalizedString("mystring",comment:"")
    }
}
swift 2.3也应如此(在
参数前没有下划线)

更新 这在使用闭包时需要一个变通方法,因为swift希望您将
NSLocalizedString
self
一起使用,就像这样,
self.NSLocalizedString(“mystring”,注释:)
。 此场景中的解决方法是将字符串分配给闭包外部的
let
/
var

例子: 对于属性初始值设定项,编译器将使用静态函数,这就是为什么必须同时设置它们

例子:

您的意思是为每个类创建名为NSLocalizedString的不同函数是的,或者只创建一个函数,该函数接受
任何
,但我再次建议您将该函数命名为其他函数,并将我的答案标记为已接受,如果它对您有帮助。否,这对我没有帮助。我已经知道它可以与自定义函数一起工作,但我需要重新定义,再次阅读我的问题,如果你能提供一些上下文,比如为什么这是必要的,以及你将传递它的确切参数,这会有所帮助。我只是问,因为这似乎是一个非常罕见的用例。ScEnvio是我们调用这个方法在100个以上的类,所以现在我们试图重写这个方法01:01的地方来处理语言回落的情况下,你是否考虑方法浸泡?下面是一个如何在swift中实现的示例。我们可以对类和实例方法使用swizzling。但是,如何对全局函数进行swizzling,NSLocalizedString就像swift中的全局函数,可以在没有任何类或对象引用的情况下调用。这一要求非常“不寻常”。你想实现什么?你是对的,我的错,完全错过了您将在项目中重新定义新版本的部分。它是一个全局函数或协议方法或其他任何东西。我是否需要在我已经调用此方法的每个类中重新定义它?当我们在闭包和属性初始值设定项中调用NSLocalizedString方法时,您的解决方案也不起作用,您需要传递该类的引用才能调用此方法。@SumitDhariwal您可以在任何类之外的项目中定义新版本。这是一个全局函数。如果要使用新的实现,必须在类中重新定义它(仅当需要新的实现时,否则它将只取范围中最接近的实现)。该解决方案也适用于闭包,它使用最接近已定义块的作用域的函数。请尝试在property Initializer和closoures中调用NSLocalizedString。您的意思是需要
self
会破坏您试图实现的行为吗?您始终可以将所需字符串分配给闭包外部的
let
,并在内部使用
let
let string=NSLocalizedString(“mystring”,注释:“”);self.present(anotherVc,animated:true){[weak self]in self?.myLabel.text=string}
对于属性初始值设定项,编译器使用静态函数您的意思是对self的需要会破坏您试图实现的行为吗?-对更新您的答案您试图建议的内容。由于第三方库的使用,您不能在闭包之外设置字符串吗?还是说这只是太多的开销?
 // Doesn't work
 self.present(anotherVc, animated: true) { [weak self] in
      self?.myLabel.text = NSLocalizedString("mystring", comment: "") // compiler will throw an error
 } 
 // Does work
 let string = NSLocalizedString("mystring", comment: "")
 self.present(anotherVc, animated: true) { [weak self] in
      self?.myLabel.text = string 
 } 
class MyClass: NSObject {
   // This let
   let myStr = NSLocalizedString("mystring",comment:"")
}

extension NSObject {
    func NSLocalizedString(_ key: String, comment: String) -> String {
        return "My custom localization"
    }
    // Uses the static method    
    static func NSLocalizedString(_ key: String, comment: String) -> String {
        return "My custom localization"
    }
}