【发布时间】:2014-09-19 18:37:21
【问题描述】:
这是一个非常简单的类(NSObject 的子类),它保留了一个 CGPath 对象列表并将一个 CGPath 附加到 init 上的数组中:
import Foundation
class MyClass: NSObject {
var list = [CGPath]();
init() {
list.append(CGPathCreateMutable());
}
}
尝试使用此类时:
var instance = MyClass();
println(instance.list.count); // runtime error after adding this line
产生丑陋的崩溃:
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0x1251d1, 0x00000001064ce069 libswiftFoundation.dylib`partial apply forwarder for Swift._ContiguousArrayBuffer.(_asCocoaArray <A>(Swift._ContiguousArrayBuffer<A>) -> () -> Swift._CocoaArray).(closure #1) with unmangled suffix "392" + 121, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #0: 0x00000001064ce069 libswiftFoundation.dylib`partial apply forwarder for Swift._ContiguousArrayBuffer.(_asCocoaArray <A>(Swift._ContiguousArrayBuffer<A>) -> () -> Swift._CocoaArray).(closure #1) with unmangled suffix "392" + 121
frame #1: 0x00000001064ce0d8 libswiftFoundation.dylib`partial apply forwarder for reabstraction thunk helper <T_0_0> from @callee_owned (@in T_0_0) -> (@owned Swift.AnyObject) to @callee_owned (@in T_0_0) -> (@out Swift.AnyObject) with unmangled suffix "395" + 56
frame #2: 0x00000001057bf29a libswift_stdlib_core.dylib`Swift.MapSequenceGenerator.next <A : Swift.Generator, B>(@inout Swift.MapSequenceGenerator<A, B>)() -> Swift.Optional<B> + 554
frame #3: 0x00000001057bf49a libswift_stdlib_core.dylib`protocol witness for Swift.Generator.next <A : Swift.Generator>(@inout Swift.Generator.Self)() -> Swift.Optional<Swift.Generator.Self.Element> in conformance Swift.MapSequenceGenerator : Swift.Generator + 58
frame #4: 0x00000001064d8e97 libswiftFoundation.dylib`Swift._copyCollectionToNativeArrayBuffer <A : protocol<Swift._Collection, Swift._Sequence_>>(A) -> Swift._ContiguousArrayBuffer<A.GeneratorType.Element> + 1511
frame #5: 0x00000001064f1951 libswiftFoundation.dylib`protocol witness for Swift.Sequence.~> @infix <A : Swift.Sequence>(Swift.Sequence.Self.Type)(Swift.Sequence.Self, (Swift._CopyToNativeArrayBuffer, ())) -> Swift._ContiguousArrayBuffer<Swift.Sequence.Self.GeneratorType.Element> in conformance Swift.LazyRandomAccessCollection : Swift.Sequence + 449
frame #6: 0x00000001064daf7b libswiftFoundation.dylib`Swift.ContiguousArray.map <A>(Swift.ContiguousArray<A>)<B>((A) -> B) -> Swift.ContiguousArray<B> + 1339
frame #7: 0x00000001064da9cb libswiftFoundation.dylib`Swift._ContiguousArrayBuffer._asCocoaArray <A>(Swift._ContiguousArrayBuffer<A>)() -> Swift._CocoaArray + 475
frame #8: 0x00000001064ced3e libswiftFoundation.dylib`Swift._ArrayBuffer._asCocoaArray <A>(Swift._ArrayBuffer<A>)() -> Swift._CocoaArray + 78
frame #9: 0x000000010649f583 libswiftFoundation.dylib`Foundation._convertArrayToNSArray <A>(Swift.Array<A>) -> ObjectiveC.NSArray + 35
frame #10: 0x000000011163b40e
第 9 帧引起了我的注意:libswiftFoundation.dylib\`Foundation._convertArrayToNSArray。为什么 swift 会尝试将我漂亮、快乐的 Swift 数组转换为 NSArray?
仅当在数组中使用 CFType 对象时才会出现此问题。我可以在数组中使用NSObject 子类就好了(例如[UIBezierPath])
这个问题可以通过不继承 NSObject 轻松解决,但是我想知道 swift 到底对我无辜的数组做了什么。 另外,我如何将still use NSObject 作为基类并拥有CFType 对象的数组,例如CGPath。
还指出 (谢谢,@user102008!),它不必是 NSObject 的子类,但该属性只需声明为 @objc。
some documentation 的目的是使用 @objc 并在 Swift 中继承一个 Objective-C 类:
当你定义一个继承自 NSObject 或任何其他的 Swift 类时 Objective-C 类,该类自动兼容 Objective-C。
但是,我正在尝试在 Swift 中使用我的 Swift 类。当子类化一个 Objective-C 类并在 Swift 中使用它时,文档中没有提到不同行为的副作用。但文档还提到将 Swift 数组桥接到NSArray:
当您从 Swift 数组桥接到
NSArray对象时,元素 在 Swift 数组中必须与AnyObject兼容。
接着说:
如果 Swift 数组中的元素与
AnyObject不兼容,则在桥接到NSArray对象时会出现运行时错误。
嗯,CGPath 与 AnyObject 不兼容,但 Swift不应该试图将我的 Swift 数组转换为 NSArray。
【问题讨论】:
-
顺便说一句:该类甚至不必继承
NSObject;只需声明该属性@objc即可发生此问题 -
@user102008 不错的收获!
-
“CGPath 与 AnyObject 不兼容” 是什么让你这么说?它似乎适合我。
-
@newacct 我猜真的是 CGPath 与 NSObject 不兼容,这意味着它不能在 NSArray 中。
-
更新:这已在 Xcode 6 beta 5 中修复