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

时间:2017-11-01 11:12:41

标签: swift localization preprocessor-directive nslocalizedstring xcode8.1

我想在swift 2.3中取消定义或覆盖NSLocalizedString,然后我搜索了很多关于它的内容,最后我在Objective C中找到了一种方法来执行此操作,如下所示。

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) your_function_name

我想在swift中实现这个功能。 我只知道NSLocalizedString是目标C的NSBundle.h中的一个宏。所以我们可以重新定义它。但是对于swift我们无法实现这一点。我只想重新定义或覆盖swift的NSLocalizedString函数.Please帮助我解决这个问题。非常感谢。

3 个答案:

答案 0 :(得分:0)

#undefC preprocessor directive和Swift does not support any preprocessor directives,包括用于#define的复杂NSLocalizedString宏。实际上,它导入为:

/// 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"
}

但请不要这样做。创建一个不同的功能会更好更多。否则,您的功能是否正在使用是不明确的,或者如果您需要更改签名,您可能会得到:error: ambiguous use of 'NSLocalizedString(_:tableName:bundle:value:comment:)',即使您只是想做一些可选的。

答案 1 :(得分:0)

NSLocalicedString是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"

答案 2 :(得分:0)

找到this,只有在边课中使用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,

应该是相同的(在key param之前没有下划线)

更新

在使用闭包时需要一种解决方法,因为swift会期望您使用NSLocalizedStringself这样的self.NSLocalizedString("mystring",comment:"")。 此方案中的解决方法是将字符串分配给闭包外的let / var

实施例

 // 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"
    }
}