【问题标题】:Swift Inheritance Issue - Cannot access inherited propertiesSwift 继承问题 - 无法访问继承的属性
【发布时间】:2014-11-10 22:11:33
【问题描述】:

我遇到了一个奇怪的问题,它涉及 Swift 中的简单继承。我可能会做一些完全愚蠢的事情,所以如果有人有任何建议..提前谢谢!

我正在使用最新的 XCode 6 GM 版本 6A313。

以下是使 Objective-C 向后兼容的 2 个 Swift 类。

@objc
public class ObjectA : NSObject {
    var testProp: String!

    init(testProp: String) {
        self.testProp = testProp
    }
}

@objc
public class ObjectB : ObjectA {
    var testPropB: String!

    init(testProp: String, testPropB: String) {
        self.testPropB = testPropB
        super.init(testProp: testProp)
    }
}

然后我在 Objective-C 代码中初始化并使用该对象。

ObjectB *objectB = [[ObjectB alloc] initWithTestProp: @"TestProp" testPropB: @"TestPropB"];
// This executes correctly and has the correct value
NSLog(@"%@", objectB.testPropB);

// I then pass this newly constructed object to another class that's written in Swift
AnotherClass *anotherClass = [[AnotherClass alloc] init];
[anotherClass someMethod:objectB];

这是 Swift 类,当我尝试访问继承的属性时,我得到一个 EXC_BAD_ACCESS 代码 1。

@objc
public class AnotherClass : NSObject {

    public func someMethod(objectB: ObjectB) {
        // This executes and assigns correctly
        let prop = objectB.testProp

        // This errors out with EXC_BAD_ACCESS error code 1
        // In the debugger, objectB.testPropB actually seem to have the correct value
        let propB = objectB.testPropB 
    }
}

【问题讨论】:

  • Objective-C 可以挤进“Swift”源代码中的量……
  • 是的。我们正在从 Swift 过渡到 Objective-C,所以很遗憾它会在一段时间内看起来非常混合。
  • 我会专门针对nil 测试objectB.testPropB。另外,您确定AnotherClass.propBObjectB.testPropB 属于同一类型吗?
  • 我试图检查 objectB.testPropB 与 nil,但调用 objectB.testPropB 的行为给了我一个 EXC_BAD_ACCESS。此外,我已经消除了 AnotherClass.propB 并简单地在 objectB.testPropB 上使用 NSLog 但仍然没有继续...

标签: objective-c inheritance swift xcode6


【解决方案1】:
var testProp: String!

没有理由将其作为隐式展开的可选项。你总是在init 中初始化它。如果可能的话,应该是:

let testProp: String

如果它必须在赋值后是可变的,那么它应该是:

var testProp: String

修复此问题可能会导致编译器在您做错了什么的地方大喊大叫(可能不在您在此处发布的代码中)。使用!,初始化此值失败是合法的(稍后您将崩溃)。如果没有!,编译器会更好地验证您是否初始化了这个值。

这一行:

ObjectB *objectB = [[ObjectB alloc] initWithTestProp: @"TestProp", testPropB: @"TestPropB"];

不正确的 ObjC(有一个额外的逗号)。我会假设这是一个错字。我不认为会导致合法的 C 逗号运算符导致错误的初始化程序运行。但也许......至少值得检查一下你是否真的有逗号。 (我很确定testPropB:@"..." 不是一个合法的表达方式,所以这有点牵强,但它会符合你的症状)。

【讨论】:

  • 感谢您的建议。你是对的,逗号是一个错字。我删除了感叹号,编译器没有抱怨,但不幸的是,这并没有解决问题。我认为其他一切都应该是准确的。
【解决方案2】:

因此,我最终创建了一个虚拟项目,以在更可控的环境中测试我的理论。修复基本上是为了确保 ObjectA 和 ObjectB 在 2 个单独的 Swift 文件中。当它们在同一个 Swift 文件中时,就会发生错误。

这里是任何感兴趣的人的示例代码。

https://github.com/MystKnight/swift-inheritance-test

我不确定为什么会这样,但是对于那里的每个人,如果您使用继承,我想将您的文件限制为一个类...

【讨论】:

  • 这是一个令人讨厌的编译器错误,您应该将它提交给 Apple。尝试向 ObjectB 添加几个方法,例如 test1() 和 test2(),然后尝试从 AnotherObject 调用这些方法。如果你调用 test2(),你最终会进入 test1()。如果你调用 test1() 你最终会进入 init() (并且会崩溃)。
猜你喜欢
  • 2019-10-21
  • 2021-11-12
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多