这是一个非常简单的类(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 类:
When you define a Swift class that inherits from NSObject or any other Objective-C class, the class is automatically compatible with Objective-C.
但是,我正在尝试在 Swift 中使用我的 Swift 类。在对 Objective-C 类进行子类化并在 Swift 中使用它时,不同行为的文档中没有提到副作用。但文档还提到将 Swift 数组桥接到 NSArray
。 :
When you bridge from a Swift array to an
NSArray
object, the elements in the Swift array must beAnyObject
compatible.
接着说:
If an element in a Swift array is not
AnyObject
compatible, a runtime error occurs when you bridge to anNSArray
object.
嗯嗯,CGPath
不是 AnyObject
兼容,但 Swift 不应该 尝试将我的 Swift 数组转换为 NSArray
.
最佳答案
Hmmmm, CGPath isn't AnyObject compatible, but Swift shouldn't be trying to convert my Swift array into an NSArray.
必须的。你说你希望它与 ObjC 兼容,而 ObjC 不能直接处理 Swift 数组。所以它必须将其转换为 NSArray。
简短的回答是,这完全按照记录工作。由于这是 iOS,因此解决方案很简单。只需切换到 UIBezierPath(与 AnyObject 兼容)而不是 CGPath。
关于ios - 在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24997536/