在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误 [英] Runtime error when using CoreFoundation objects in a swift NSObject subclass

查看:28
本文介绍了在 swift NSObject 子类中使用 CoreFoundation 对象时出现运行时错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个非常简单的类(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 be AnyObject compatible.

接着说:

如果 Swift 数组中的元素与 AnyObject 不兼容,则在桥接到 NSArray 对象时会发生运行时错误.

If an element in a Swift array is not AnyObject compatible, a runtime error occurs when you bridge to an NSArray object.

嗯,CGPathAnyObject 不兼容,但 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆