我试图在swift 3中创建一个类来实现cordova插件。我已经构建并运行了这个程序,但是只要访问类的任何属性,应用程序就会崩溃。我尝试了两种初始化类的方法:
@objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players = [UUID:DSFPlayerHandler] ();
...
}
和
@objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler];
override init () {
players = [:];
}
...
}
但是,当使用my
players
属性时,结果是exc_bad_access异常,地址看起来像空指针取消引用。对象是由目标C代码创建的,这是一种我完全不熟悉的语言,但我认为这是创建它的行:
obj = [[NSClassFromString(className)alloc] initWithWebViewEngine:_webViewEngine];
CDVPlugin
类包含一个说明不应重写initWithWebViewEngine
的注释(实际上,我似乎无法重写此方法,因为当它在CDVPlugin.m
文件中声明时,它在CDVPlugin.h
中没有提到,因此swift编译器似乎不知道它),而是初始化代码。应该放在名为pluginInitialize
的方法中。但是,如果这样做,我会得到一个编译器错误(“类dsfmediacenter没有初始值设定项”)。此外,如果我将我的
init()
方法放回并将其设置为callpluginInitialize()
,如下所示:override init () {
super.init(); // necessary otherwise next line is an error
pluginInitialize();
}
override func pluginInitialize() {
players = [:];
}
然后错误变为“property”self.players“not initialized at super.init call”。
如何使该类正确初始化?
最佳答案
语言所需的严格初始化系统与正在使用的框架所使用的过程不匹配。
swift要求a)将属性初始化为对象构造的一部分,b)将构造链接到类型的父类型。但是,CDVPlugin
类型是代表您进行构造;您没有能力自定义它。(这在objc中更有意义,因为它没有与swift相同的编译时间限制。)
这种情况类似于从nib文件中解压对象。在这种情况下,也一样,因为构建对象的是NIB加载系统,所以您没有能力自定义初始值设定项。您的类型将始终由init(coder:)
构造。在某种意义上,您的初始化点会进一步向下移动,直到awakeFromNib()
,并且在其他事情中,强制将档案中其他对象的出口声明为可选,通常是隐式展开的。
同样的解决方案也会对你有所帮助。您应该考虑将pluginInitialize()
作为初始化点。然后,语言要求属性是可选的,因为它们在初始化点没有被填充。因此,将该财产设为IUO:
@objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler]!
override func pluginInitialize() {
players = [:];
}
}
一切都会好起来的。
关于objective-c - 当由Objective C代码构造时,未初始化Swift类属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47737489/