使用迅速NSObject的子类的CoreFoundation对象时运行时错误 [英] Runtime error when using CoreFoundation objects in a swift NSObject subclass

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

问题描述

下面是一个非常简单的类(子类 NSObject的),保持 CGPath 对象的列表,并附加有一个 CGPath 数组初始化

 进口基金会
MyClass类:NSObject的{    VAR名单= [CGPath]();    在里面() {
        list.append(CGPathCreateMutable());
    }
}

当尝试使用这个类:

  VAR实例= MyClass的();
的println(instance.list.count); //加入这一行后,运行时错误

产生一个丑陋的崩溃:

 游乐场执行失败:错误:执行被中断,原因是:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,分code =为0x0)。
这个过程一直留在它被中断的点,用主题返回-x前pression评价前返回的状态。
*线#1:TID = 0x1251d1,0x00000001064ce069 libswiftFoundation.dylib`partial为Swift._ContiguousArrayBuffer申请代理(_ asCocoaArray< A>(Swift._ContiguousArrayBuffer< A>) - GT;() - GT; Swift._CocoaArray)(关闭#1)重整的后缀392+ 121,队列='com.apple.main线程,停止的原因= EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,分code =为0x0)
  *帧#0:0x00000001064ce069 libswiftFoundation.dylib`partial申请转发器Swift._ContiguousArrayBuffer(_ asCocoaArray< A>(Swift._ContiguousArrayBuffer< A>) - GT;() - GT; Swift._CocoaArray)(关闭#1)与重整的后缀392+ 121
    帧#1:0x00000001064ce0d8 libswiftFoundation.dylib`partial申请转发器reabstraction thunk的助手< T_0_0>从@callee_owned(@In T_0_0) - GT; (@owned Swift.AnyObject)到@callee_owned(@In T_0_0) - GT; (@out Swift.AnyObject)与重整的后缀395+ 56
    帧#2:0x00000001057bf29a libswift_stdlib_core.dylib`Swift.MapSequenceGenerator.next< A:Swift.Generator,B>(@ INOUT Swift.MapSequenceGenerator< A,B>)() - GT; Swift.Optional< B> + 554
    帧#3:Swift.Generator.next&LT 0x00000001057bf49a libswift_stdlib_core.dylib`protocol见证; A:Swift.Generator>(@ INOUT Swift.Generator.Self)() - GT; Swift.Optional< Swift.Generator.Self.Element>在一致性Swift.MapSequenceGenerator:Swift.Generator + 58
    帧#4:0x00000001064d8e97 libswiftFoundation.dylib`Swift._copyCollectionToNativeArrayBuffer< A:协议< Swift._Collection,Swift._Sequence_>>(A) - GT; Swift._ContiguousArrayBuffer< A.GeneratorType.Element> + 1511
    帧#5:0x00000001064f1951为Swift.Sequence libswiftFoundation.dylib`protocol见证〜方式> @infix< A:Swift.Sequence>(Swift.Sequence.Self.Type)(Swift.Sequence.Self,(Swift._CopyToNativeArrayBuffer,())) - > Swift._ContiguousArrayBuffer< Swift.Sequence.Self.GeneratorType.Element>在一致性Swift.LazyRandomAccessCollection:Swift.Sequence + 449
    帧#6:0x00000001064daf7b libswiftFoundation.dylib`Swift.ContiguousArray.map< A>(Swift.ContiguousArray< A>)< B>((A) - > B) - > Swift.ContiguousArray< B> + 1339
    帧#7:0x00000001064da9cb libswiftFoundation.dylib`Swift._ContiguousArrayBuffer._asCocoaArray< A>(Swift._ContiguousArrayBuffer< A>)() - GT; Swift._CocoaArray + 475
    帧#8:0x00000001064ced3e libswiftFoundation.dylib`Swift._ArrayBuffer._asCocoaArray< A>(Swift._ArrayBuffer< A>)() - GT; Swift._CocoaArray + 78
    帧#9:0x000000010649f583 libswiftFoundation.dylib`Foundation._convertArrayToNSArray< A>(Swift.Array< A>) - GT; ObjectiveC.NSArray + 35
    帧#10:0x000000011163b40e

框#9抓住了我的眼球: libswiftFoundation.dylib \\`Foundation._convertArrayToNSArray 。为什么会迅速试图我漂亮,快乐,斯威夫特数组转换成的NSArray

只有在一个阵列使用 CFType 对象时出现此问题。我可以在阵列中使用 NSObject的子就好了(例 [UIBezierPath]

问题可以很容易地通过不继承 NSObject的是固定的,但是我想知道究竟迅速在做我的清白阵列同时,我怎么可以仍然可以使用 NSObject的 作为基类,有数组 CFType 对象,如 CGPath

也有人指出的(感谢@ user102008!)的,它并没有成为 NSObject的的子类,但物业只是要声明 @objc

有<一个href=\"https://developer.apple.com/library/$p$prelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_36\"相对=nofollow>一些文档使用的目的 @objc 和斯威夫特继承的Objective-C类的:


  

当你定义从NSObject的或其他任何继承的类斯威夫特
  Objective-C类,这个类是自动兼容
  Objective-C的。


不过,我从内斯威夫特尝试使用雨燕我的班。有没有副作用继承的Objective-C类和斯威夫特在使用它时,不同的行为的文件中提及。但是,文件中还提到桥接斯威夫特阵列的NSArray


  

当您从斯威夫特阵列的的NSArray 对象桥,元素
  雨燕数组中必须 AnyObject 兼容。


和接着说:


  

如果在斯威夫特数组中的元素不是 AnyObject 兼容,当你缩小到的NSArray 对象。


嗯, CGPath 不是 AnyObject 兼容,但斯威夫特的不应该的试图我斯威夫特数组转换成的NSArray


解决方案

  

嗯,CGPath不AnyObject兼容,但斯威夫特不应该尝试我的雨燕数组转换成一个NSArray。


它必须。你说你希望它是ObjC兼容,ObjC不能直接处理斯威夫特阵列。因此它有将其转换为一个NSArray

简短的回答是,这是工作完全一样记录。由于这是iOS的,该解决方案,但是,是微不足道的。只需切换到UIBezierPath(这是AnyObject兼容),而不是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());
    }
}

When trying to use this class:

var instance = MyClass();
println(instance.list.count); // runtime error after adding this line

Yields an ugly crash:

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

Frame #9 caught my eye: libswiftFoundation.dylib\`Foundation._convertArrayToNSArray. Why would swift be trying to convert my nice, happy, Swift array into an NSArray?

This issue only occurs when using CFType objects in an array. I can use NSObject subclasses in the array just fine (Ex. [UIBezierPath])

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.

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.

There is some documentation on purpose of using @objc and subclassing an Objective-C class in Swift:

When you define a Swift class that inherits from NSObject or any other Objective-C class, the class is automatically compatible with Objective-C.

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:

When you bridge from a Swift array to an NSArray object, the elements in the Swift array must be AnyObject compatible.

And goes on to say:

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

Hmmmm, CGPath isn't AnyObject compatible, but Swift shouldn't be trying to convert my Swift array into an NSArray.

解决方案

Hmmmm, CGPath isn't AnyObject compatible, but Swift shouldn't be trying to convert my Swift array into an 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.

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.

这篇关于使用迅速NSObject的子类的CoreFoundation对象时运行时错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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