我试图在swift 3中创建一个类来实现cordova插件。我已经构建并运行了这个程序,但是只要访问类的任何属性,应用程序就会崩溃。我尝试了两种初始化类的方法:

@objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
    var players = [UUID:DSFPlayerHandler] ();
    ...
}


@objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
    var players :[UUID:DSFPlayerHandler];
    override init () {
        players = [:];
    }
    ...
}

但是,当使用myplayers属性时,结果是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/

10-11 22:22
查看更多