在IOS SWIFT中,如何实现类似的功能,例如C#中提供的 静态构造函数 。
即:
这是设置全局翻译映射,以使用提供的名称而不是真实的类名称(类名称为“ Order”)对类的实例进行编码。
NSKeyedUnarchiver.setClass(Order.self, forClassName: "OldModuleName.Order")
从begininig编写旧的APP(用SWIFT 1.2编写),并且项目名称不同,因此模块名称与旧版本不同。
我需要在初始化类之前一次运行上述代码。
class Order: NSObject, NSCoding
{
var orderID: Int = 0
var description: String = ""
// NEED TO RUN THIS LINE BEFORE INIT METHOD >>>>
// NSKeyedUnarchiver.setClass(Order.self, forClassName: "OldModuleName.Order")
override init()
{
super.init()
}
required init?(coder aDecoder: NSCoder)
{
self.orderID = (aDecoder.decodeInteger(forKey: "OrderID"))
self.description= (aDecoder.decodeObject(forKey: "Description") as? String) ?? ""
}
func encode(with aCoder: NSCoder)
{
aCoder.encode(self.orderID, forKey: "OrderID")
aCoder.encode(self.description, forKey: "Description")
}
}
编辑
我尝试编写如下所示的静态常量,并在“ 必需的init?(coder aDecoder:NSCoder) ”方法中对其进行调用(因为此类符合NSCoding协议在这种情况下,不会调用默认的init方法)
static let ConfigureEncodeTranslationMapping: Void =
{
NSKeyedUnarchiver.setClass(Order.self, forClassName: "OldModuleName.Order")
return()
}()
required init?(coder aDecoder: NSCoder)
{
// call static constant here to test
Order.ConfigureEncodeTranslationMapping
self.orderID = (aDecoder.decodeInteger(forKey: "OrderID"))
self.description= (aDecoder.decodeObject(forKey: "Description") as? String) ?? ""
}
但是APP崩溃了
*由于未捕获的异常'NSInvalidUnarchiveOperationException'而终止应用程序,原因:'***-[NSKeyedUnarchiver encodeObjectForKey:]:无法解码键(NS.objects)的类(OldModuleName.Order)的对象,因为没有名为“ OldModuleName”的类“订单”已找到;该类需要在源代码中定义或从库中链接(确保该类是正确目标的一部分)。如果重命名了类,请使用setClassName:forClass:将类转换映射添加到NSKeyedUnarchiver *
答案 0 :(得分:0)
有一个名为load()
的类方法,该方法在每次加载类时自动调用,并在每次应用启动时自动调用一次。但是它定义了Objective-C类方法“加载”,这是 Swift 所不允许的。您可以使用Objective-C类并将其桥接回Swift。
尝试此操作以查看问题:
override class func load() {
print("Loaded")
}
这是动态行为, Swift 是静态的!因此,如果没有Objective-C的帮助,您将无法迅速完成此任务。
您可以拥有一个静态常量,然后调用一次(或多次,无关紧要):
class Order {
static let loadOnce: Void = { print("Loaded") }()
}
Order.loadOnce
Order.loadOnce
Order.loadOnce
Order.loadOnce
查看输出显示它刚刚被调用为once
,而无需加载该类。因此,您可以使用以下命令确保在初始化完成之前调用它。
init() { Self.loadOnce }
或者甚至在致电super.init
override init() {
Self.loadOnce
super.init()
}