Вот очень простой класс (подкласс 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 делает с моим невинным массивом. Кроме того, как я могу по-прежнему использовать NSObject
в качестве базового класса и иметь массивы CFType
объектов, таких как CGPath
сильный>.
Также было указано, (Спасибо, @user102008!), что это не обязательно должен быть подкласс NSObject
, но свойство просто должно быть объявлено как @objc
.
Существует некоторая документация с целью использования @objc
и создания подклассов класса Objective-C в Swift:
Когда вы определяете класс Swift, который наследуется от NSObject или любого другого класса Objective-C, этот класс автоматически совместим с Objective-C.
Тем не менее, я пытаюсь использовать свой класс Swift из Swift. В документации по различному поведению при создании подкласса класса Objective-C и использовании его в Swift нет упоминания о побочных эффектах. Но в документации также упоминается соединение массивов Swift с NSArray
:
Когда вы соединяете массив Swift с объектом
NSArray
, элементы в массиве Swift должны быть совместимы сAnyObject
.
И продолжает:
Если элемент массива Swift несовместим с
AnyObject
, при соединении с объектомNSArray
возникает ошибка времени выполнения.
Хмммм, CGPath
не совместим с AnyObject
, но Swift не должен пытаться преобразовать мой массив Swift в NSArray
.
NSObject
; свойство просто нужно объявить@objc
для возникновения этой проблемы - person user102008   schedule 30.07.2014CGPath
NSObject
совместим во время выполнения.(CGPathCreateMutable() as AnyObject) is NSObject
оценивается как истина. - person newacct   schedule 05.08.2014If you never import a Swift class in Objective-C code, you don’t need to worry about type compatibility in this case as well.
- person Andrew   schedule 05.08.2014