在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误 [英] Runtime error when using CoreFoundation objects in a swift NSObject subclass
问题描述
这是一个非常简单的类(NSObject
的子类),它保存一个 CGPath
对象列表,并将一个 CGPath
附加到 CGPath
上的数组代码>初始化代码>:
Here's a very simple class (subclass of NSObject
) that keeps a list of CGPath
objects and appends one CGPath
to the array on 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
?
Frame #9 caught my eye: libswiftFoundation.dylib\`Foundation._convertArrayToNSArray
. Why would swift be trying to convert my nice, happy, Swift array into an NSArray
?
只有在数组中使用 CFType
对象时才会出现此问题.我可以在数组中使用 NSObject
子类就好了(例如 [UIBezierPath]
)
This issue only occurs when using CFType
objects in an array. I can use NSObject
subclasses in the array just fine (Ex. [UIBezierPath]
)
这个问题可以通过不继承 NSObject
轻松解决,但是我想知道 swift 对我无辜的数组做了什么.另外,我如何仍然使用 NSObject
作为基类并拥有CFType
对象,例如 CGPath
.
The issue can easily be fixed by not subclassing NSObject
, however I want to know what exactly swift is doing to my innocent array. Also, how I can still use NSObject
as the base class and have arrays of CFType
objects such as CGPath
.
还有人指出(谢谢,@user102008!)它不必是 NSObject
的子类,但必须声明该属性@objc
.
It was also pointed out (Thanks, @user102008!) that it doesn't have to be a subclass of NSObject
, but the property just has to be declared @objc
.
有 一些文档,目的是使用 @objc
并在 Swift 中对 Objective-C 类进行子类化:
There is some documentation on purpose of using @objc
and subclassing an Objective-C class in Swift:
当你定义一个继承自 NSObject 或任何其他的 Swift 类时Objective-C 类,该类自动兼容目标-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
:
However, I am trying the use my Swift class from within Swift. There is no mention of side effects in the documentation of different behavior when subclassing an Objective-C class and using it within Swift. But the documentation also mentions bridging Swift arrays to NSArray
:
当你从一个 Swift 数组桥接到一个 NSArray
对象时,元素在 Swift 数组中必须与 AnyObject
兼容.
When you bridge from a Swift array to an
NSArray
object, the elements in the Swift array must beAnyObject
compatible.
接着说:
如果 Swift 数组中的元素与 AnyObject
不兼容,则在桥接到 NSArray
对象时会发生运行时错误.
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
.
推荐答案
嗯,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.
It has to. You said you want it to be ObjC compatible, and ObjC can't handle Swift arrays directly. So it has to convert it to an NSArray.
简短的回答是,这完全按照文档工作.由于这是 iOS,因此解决方案很简单.只需切换到 UIBezierPath(与 AnyObject 兼容)而不是 CGPath.
The short answer is that this is working exactly as documented. Since this is iOS, the solution, however, is trivial. Just switch to UIBezierPath (which is AnyObject compatible) rather than CGPath.
这篇关于在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!