子类化 NSObject 和使用泛型时 Swift 编译错误

Posted

技术标签:

【中文标题】子类化 NSObject 和使用泛型时 Swift 编译错误【英文标题】:Swift compile error when subclassing NSObject and using generics 【发布时间】:2014-06-11 11:17:12 【问题描述】:

以下 Swift 代码在构建时生成编译错误:

import Foundation

class Wrapper<T> : NSObject 
    let obj : T

    init(x : T) 
        self.obj = x
    

是我做错了什么还是编译器错误?

如果是这样,我可以做些什么来解决它?

错误日志:

CompileSwift normal i386 com.apple.xcode.tools.swift.compiler
    cd /Users/hermespique/workspace/HanekeSwift
    export PATH="/Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode6-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -target i386-apple-ios8.0 -module-name HanekeTests -O0 -sdk /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk -g -module-cache-path /Users/hermespique/Library/Developer/Xcode/DerivedData/ModuleCache -I /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator -F /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/Developer/Library/Frameworks -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/Developer/Library/Frameworks -c -j4 /Users/hermespique/workspace/HanekeSwift/HanekeTests/XCTestCase+Assert.swift /Users/hermespique/workspace/HanekeSwift/HanekeTests/Cache.swift /Users/hermespique/workspace/HanekeSwift/HanekeTests/Wrapper.swift -output-file-map /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/HanekeTests-OutputFileMap.json -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/HanekeTests.swiftmodule -Xcc -iquote -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-generated-files.hmap -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-own-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-project-headers.hmap -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator/include -Xcc -I/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/DerivedSources/i386 -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -DDEBUG=1 -emit-objc-header -emit-objc-header-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/HanekeTests-Swift.h

0  swift                    0x000000010a889608 llvm::sys::PrintStackTrace(__sFILE*) + 40
1  swift                    0x000000010a889af4 SignalHandler(int) + 452
2  libsystem_platform.dylib 0x00007fff88e185aa _sigtramp + 26
3  libsystem_platform.dylib 0x00007fff55fb0334 _sigtramp + 3440999844
4  swift                    0x0000000109c87395 swift::irgen::IRGenFunction::emitTypeMetadataRef(swift::CanType) + 21
5  swift                    0x0000000109cbcfb8 (anonymous namespace)::OpaqueArchetypeTypeInfo::destroy(swift::irgen::IRGenFunction&, swift::irgen::Address, swift::CanType) const + 24
6  swift                    0x0000000109cf467b swift::SILVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::ValueBase*) + 23579
7  swift                    0x0000000109cee266 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 8678
8  swift                    0x0000000109c6f6f8 swift::irgen::IRGenModule::emitGlobalTopLevel() + 184
9  swift                    0x0000000109cdb6e3 performIRGeneration(swift::IRGenOptions&, swift::Module*, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, swift::SourceFile*, unsigned int) + 1859
10 swift                    0x0000000109cdc033 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, unsigned int) + 51
11 swift                    0x0000000109c4e65a frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 4842
12 swift                    0x0000000109c4d35d main + 1533
13 libdyld.dylib            0x00007fff8ddbb5fd start + 1
14 libdyld.dylib            0x0000000000000040 start + 1914980932
Stack dump:
0.  Program arguments: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c /Users/hermespique/workspace/HanekeSwift/HanekeTests/XCTestCase+Assert.swift /Users/hermespique/workspace/HanekeSwift/HanekeTests/Cache.swift -primary-file /Users/hermespique/workspace/HanekeSwift/HanekeTests/Wrapper.swift -enable-objc-attr-requires-objc-module -target i386-apple-ios8.0 -module-name HanekeTests -sdk /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk -I /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator -F /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/Developer/Library/Frameworks -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -F /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/Developer/Library/Frameworks -g -module-cache-path /Users/hermespique/Library/Developer/Xcode/DerivedData/ModuleCache -Xcc -iquote -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-generated-files.hmap -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-own-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/HanekeTests-project-headers.hmap -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Products/Debug-iphonesimulator/include -Xcc -I/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/DerivedSources/i386 -Xcc -I/Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -DDEBUG=1 -emit-module-doc-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/Wrapper~partial.swiftdoc -O0 -emit-module-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/Wrapper~partial.swiftmodule -serialize-diagnostics-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/Wrapper.dia -emit-dependencies-path /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/Wrapper.d -o /Users/hermespique/Library/Developer/Xcode/DerivedData/Haneke-dsgqpxenngbaqpctbkhhwtqbiorj/Build/Intermediates/Haneke.build/Debug-iphonesimulator/HanekeTests.build/Objects-normal/i386/Wrapper.o 
1.  While emitting IR SIL function @_TToFC11HanekeTests7WrapperE for 'deinit' at /Users/hermespique/workspace/HanekeSwift/HanekeTests/Wrapper.swift:11:7
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254

【问题讨论】:

这看起来像是一个错误的编译器错误...时间提交错误报告。玩通用代码时编译器很崩溃 尝试删除整个 init 函数和 isEqual 函数,看看它是否可以编译,然后将它们分别添加回去,如果没有它们编译,则查看哪个破坏了它。我注意到一些 Apple 类的子类化不会与生成的 init 一起编译,因此它很可能是一个将被修复的错误。 @KrisGellci 问题似乎是子类化 NSObject、使用泛型和具有变量的组合。不确定是否有解决方法。 这里有一个更简化的问题版本:class Wrapper&lt;T&gt; : NSObject let obj : T init(x : T) self.obj = x 我在这里注意到了一个类似的问题,但没有涉及 NSObject。此处注明:***.com/questions/24193957/… 【参考方案1】:

我找到了解决这个问题的方法

class Wrapper<T> 
    let _val: T[]

    init(_ v: T) 
        _val = [v]
    

    var val : T 
        get 
            return _val[0]
        
        set 
            _val[0] = newValue
        
    

由于Array 是一个引用类型(即使它是结构),Wrapper 类的大小现在是固定的,编译器可以处理它。

【讨论】:

我很惊讶,现在 Swift 和 Xcode 6 已经发布,这仍然是必要的! 我认为这行得通的原因是你不再继承 NSObject。 NSObject 子类不能有泛型。 @Jarsen 这也适用于NSObject 子类。 是的,用 Swift 1.2 测试过。【参考方案2】:

我认为这是一个带有泛型和 NSObject 的 X 代码错误

class Foo<T>:NSObject
    let _foo:T?

    init(foo:T)
        _foo  = foo
    

给出 swiftc 失败,退出代码为 254

删除 NSObject 工作正常。即:

class Foo<T>
    let _foo:T?

    init(foo:T)
        _foo  = foo
    

或者向泛型添加约束似乎有效。即:

class Foo<T:AnyObject>:NSObject
    let _foo:T?

    init(foo:T)
        _foo  = foo
    

【讨论】:

这里的第一个sn-p不再失败。【参考方案3】:

我摆弄了你有趣的 (+1) sn-p 代码,这是我在避免编译器错误的同时能得到的最接近的代码:

struct Wrapper<T>  
    var obj : T

    init(_ x : T) 
        obj = x
    

所以,如果你真的不需要 Wrapper 作为一个类,那么你就可以继续……直到 Xcode 的下一个版本;)

【讨论】:

【参考方案4】:

在我看来,泛型不喜欢 NSObjects 类型,只喜欢 AnyObject 类型..

NSObject 不符合 AnyObject(它们在性质和功能上有所不同).. 这意味着如果您需要创建泛型方法,则不能使用 Array 代替 NSArray。我认为这就是他们迅速离开 NSArray 的原因 .. 因为他们仍然有 NS .. 遗留的东西 .. 最重要的是 CoreData。我试图创建一个通用的 NSManagedObject 类来派生,它会使用这个强大的特性(泛型)。我做不到。

【讨论】:

【参考方案5】:

这个小代码 sn-p(我的另一个 +1)仍然会导致 Xcode 7 beta 1 中的编译器崩溃,我猜它的意图是该代码不是有效的类定义。如果 Cupertino 的任何人收听此线程,我们将不胜感激提供礼貌的错误消息而不是崩溃。

我通过约束泛型参数实现NSObjectProtocol解决了这个问题

class Wrapper<T:NSObjectProtocol> : NSObject

   let obj : T
   init(x : T)  self.obj = x 

每当TNSManagedObject 的子类时,这对我构建与Wrapper&lt;T&gt; 匹配的函数时很有用。

【讨论】:

【参考方案6】:

对于 Swift 2.0。此问题不再有效。

你可以有一个这样的类,编译器不会抱怨。

class Wrapper<T> : NSObject 
    let obj : T

    init(x : T) 
        self.obj = x
    

【讨论】:

以上是关于子类化 NSObject 和使用泛型时 Swift 编译错误的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用镜像设置Swift对象属性的值吗?

泛型总结

包含 NSObject 子类时,Swift 2.0 Set 无法按预期工作

在 NSObject 的子类上实现啥方法以允许在 swift 操场上进行漂亮的打印?

使用类型泛型时如何正确地将类转换为抽象类?

为啥在存在非泛型时选择泛型方法?