这可能是一个Swift问题,或者我不理解Swift中的泛型是如何工作的,但我使用下面的代码示例得到编译器错误/崩溃,我不明白为什么
import Foundation
import ReactiveCocoa
protocol MyErrorType {
}
enum MyCustomError: MyErrorType {
case AnError
}
enum MyCustomReactiveError: ReactiveCocoa.ErrorType {
case Foo
case Bar
var nsError: NSError {
switch self {
case .Foo:
return NSError(domain: "", code: 0, userInfo: nil)
case .Bar:
return NSError(domain: "", code: 1, userInfo: nil)
}
}
}
class Container1<T> {
let value: T
init(value: T) {
self.value = value
}
}
class Container2<E: MyErrorType> {
let error: E
init(error: E) {
self.error = error
}
}
class TestClass1<T> {
let defaultValue: T
init(defaultValue: T) {
self.defaultValue = defaultValue
}
func foo() -> Container1<T> {
return Container1(value: defaultValue)
}
}
class TestClass2<E: MyErrorType> {
let defaultValue: E
init(defaultValue: E) {
self.defaultValue = defaultValue
}
func foo() -> Container2<E> {
return Container2(error: defaultValue)
}
}
class TestClass3: TestClass1<Int> {
override func foo() -> Container1<Int> {
return Container1(value: 20)
}
}
class TestClass4: TestClass2<MyCustomError> {
override func foo() -> Container2<MyCustomError> {
return Container2(error: MyCustomError.AnError)
}
}
class TestClass5<E: ReactiveCocoa.ErrorType> {
func foo() -> SignalProducer<(), E> {
return SignalProducer.empty
}
}
class TestClass6: TestClass5<MyCustomReactiveError> {
override func foo() -> SignalProducer<(), MyCustomReactiveError> {
return SignalProducer(error: MyCustomReactiveError.Foo)
}
}
我收到以下错误
SIL verification failed: vtable entry for #TestClass5.foo!1 must be ABI-compatible
ABI-incompatible return values
@convention(method) <τ_0_0 where τ_0_0 : ErrorType> (@guaranteed TestClass5<τ_0_0>) -> @owned SignalProducer<(), τ_0_0>
@convention(method) (@guaranteed TestClass6) -> @owned SignalProducer<(), MyCustomReactiveError>
In function:
// WLXViewModel.TestClass6.foo (WLXViewModel.TestClass6)() -> ReactiveCocoa.SignalProducer<(), WLXViewModel.MyCustomReactiveError>
sil @_TFC12WLXViewModel10TestClass63foofS0_FT_GV13ReactiveCocoa14SignalProducerT_OS_21MyCustomReactiveError_ : $@convention(method) (@guaranteed TestClass6) -> @owned SignalProducer<(), MyCustomReactiveError> {
bb0(%0 : $TestClass6):
debug_value %0 : $TestClass6 // let self // id: %1
// function_ref ReactiveCocoa.SignalProducer.init <A, B where B: ReactiveCocoa.ErrorType> (ReactiveCocoa.SignalProducer<A, B>.Type)(error : B) -> ReactiveCocoa.SignalProducer<A, B>
%2 = function_ref @_TFV13ReactiveCocoa14SignalProducerCu0_Rq0_S_9ErrorType_fMGS0_q_q0__FT5errorq0__GS0_q_q0__ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : ErrorType> (@in τ_0_1, @thin SignalProducer<τ_0_0, τ_0_1>.Type) -> @owned SignalProducer<τ_0_0, τ_0_1> // user: %9
%3 = metatype $@thin SignalProducer<(), MyCustomReactiveError>.Type // user: %9
// function_ref WLXViewModel.MyCustomReactiveError.Foo (WLXViewModel.MyCustomReactiveError.Type) -> WLXViewModel.MyCustomReactiveError
%4 = function_ref @_TFO12WLXViewModel21MyCustomReactiveError3FooFMS0_S0_ : $@convention(thin) (@thin MyCustomReactiveError.Type) -> MyCustomReactiveError // user: %6
%5 = metatype $@thin MyCustomReactiveError.Type // user: %6
%6 = apply %4(%5) : $@convention(thin) (@thin MyCustomReactiveError.Type) -> MyCustomReactiveError // user: %8
%7 = alloc_stack $MyCustomReactiveError // users: %8, %9, %10
store %6 to %7#1 : $*MyCustomReactiveError // id: %8
%9 = apply %2<(), MyCustomReactiveError>(%7#1, %3) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : ErrorType> (@in τ_0_1, @thin SignalProducer<τ_0_0, τ_0_1>.Type) -> @owned SignalProducer<τ_0_0, τ_0_1> // user: %11
dealloc_stack %7#0 : $*@local_storage MyCustomReactiveError // id: %10
return %9 : $SignalProducer<(), MyCustomReactiveError> // id: %11
}
0 swift 0x000000010cba1e0b llvm::sys::PrintStackTrace(__sFILE*) + 43
1 swift 0x000000010cba254b SignalHandler(int) + 379
2 libsystem_platform.dylib 0x00007fff9117ef1a _sigtramp + 26
3 swift 0x000000010d19ba2e FirstTarget + 60550
4 swift 0x000000010cba2346 abort + 22
5 swift 0x000000010ad72c49 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function<void ()> const&) + 425
6 swift 0x000000010ad7182b (anonymous namespace)::SILVerifier::requireABICompatibleFunctionTypes(swift::CanTypeWrapper<swift::SILFunctionType>, swift::CanTypeWrapper<swift::SILFunctionType>, llvm::Twine const&) + 651
7 swift 0x000000010ad713eb swift::SILVTable::verify(swift::SILModule const&) const + 795
8 swift 0x000000010ad7223f swift::SILModule::verify() const + 447
9 swift 0x000000010adac730 swift::Lowering::SILGenModule::~SILGenModule() + 32
10 swift 0x000000010adb214b swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 923
11 swift 0x000000010adb228b swift::performSILGeneration(swift::FileUnit&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 123
12 swift 0x000000010abbb691 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&) + 9153
13 swift 0x000000010abb90b3 frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 2515
14 swift 0x000000010abb528f main + 1983
15 libdyld.dylib 0x00007fff9b1685c9 start + 1
Stack dump:
我看不出TestClass6
和TestClass4
之间有什么区别。为什么一个人编译而另一个人几乎不相同?
顺便说一下,我正在使用XCode 7.0 beta(7A120f)和ReactiveCocoa分支swift2
提交1b7e41328d22902e5357d10c38c04606be4cd478
答案 0 :(得分:0)
Apple在Swift 2中用ErrorType替换了NSError。
继续在您自己的代码中明确使用NSError在某些情况下有效但在其他情况下会导致一些奇怪的错误。
使用ErrorType替换您自己代码中NSError的所有显式用法。