ios - 在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误

标签 ios arrays swift nsobject

这是一个非常简单的类(NSObject 的子类),用于保存 CGPath 的列表。对象并附加一个 CGPathinit 上的数组:

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 be AnyObject compatible.

接着说:

If an element in a Swift array is not AnyObject compatible, a runtime error occurs when you bridge to an NSArray 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/

相关文章:

javascript - 使用 Javascript 从数组中删除项目

swift - 创建自定义 UITableView 类

ios - 即使在退出 View Controller 后也将数据保存为 UserDefault

ios - 在 Swift 中获取联系人姓名和电话号码

ios - UITableView 重叠单元格(力)

ios - Apple Pay 不会显示预填信息

javascript - 如何在 React Native 中使按钮居中

javascript - 多维数组函数在 JS 中不起作用

arrays - Powershell-如何用数组列表值替换查询结果值

objective-c - 如何检查触摸点是否在 UIBezierPath 上(iOS)