Swift: точка останова в библиотеке CoreData
XCode 6 Beta 3 с использованием Swift.
В моем приложении я использую CoreData. Когда я запускаю свое приложение в симуляторе, XCode открывает отладчик с точкой останова, установленной где-то в библиотеке CoreData (см. Скриншот). Это происходит с несколькими функциями CoreData, например, при вставке новых записей или извлечении записей из объекта. Положение точки останова всегда одинаково.
Это очень раздражает. Когда мое приложение получает 10 записей от объекта, я должен нажать кнопку продолжения выполнения программы 10 раз.
Поскольку эта точка останова установлена где-то в машинном коде, инспектор точек останова не показывает никаких точек останова, поэтому я не могу удалить ее.
Кто-нибудь знает, как от этого избавиться?
Большое спасибо.
Редактировать: backtrace-output:
(lldb) bt * thread # 1: tid = 0x1d68b0, 0x000000010a2f7fcd libswift_stdlib_core.dylib
swift_dynamicCastClassUnconditional + 77, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) * frame #0: 0x000000010a2f7fcd libswift_stdlib_core.dylib
swift_dynamicCastClassUnconditional + 77 кадров #1: 0x000000010a0fbb85 GPS-трекGPS_Track.TrackListTableViewController.tableView (tableView=<unavailable>)(Swift.ImplicitlyUnwrappedOptional<ObjectiveC.UITableView>, cellForRowAtIndexPath : Swift.ImplicitlyUnwrappedOptional<ObjectiveC.NSIndexPath>) -> Swift.Optional<ObjectiveC.UITableViewCell> + 1125 at TrackListTableViewController.swift:53 frame #2: 0x000000010a0fc937 GPS Track
@objc GPS_Track.TrackListTableViewController.tableView (GPS_Track.TrackListTableViewController)(Swift.ImplicitlyUnwrappedOptional, cellForRowAtIndexPath: Swift.-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 508 frame #4: 0x000000010bc0f340 UIKit
-[UITableView _updateVisibleCellsNow:isRecursive:] + 2845 кадра # 5: 0x000000010bc24fea UIKit-[UITableView layoutSubviews] + 213 frame #6: 0x000000010bbb1ebd UIKit
- [UIView (CALayerDelegate) layoutSublayersOfLayer:] + 519 кадр # 7: 0x000000010b9c9598 QuartzCore-[CALayer layoutSublayers] + 150 frame #8: 0x000000010b9be1be QuartzCore
CA:: Layer:: layout_if_needed (CA:: Transaction *) + 380 кадров № 9: 0x000000010b9be02e QuartzCoreCA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24 frame #10: 0x000000010b92cf16 QuartzCore
CA:: Context:: commit_transaction (CA:: Transaction *) + 242 кадра # 11: 0x000000010b92e022 QuartzCoreCA::Transaction::commit() + 390 frame #12: 0x000000010b92e68d QuartzCore
CA:: Transaction:: Observer_callback(__CFRunLoopObserver*, длинный без знака, void*) + 89 кадров # 13: 0x000000010ab52927 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23 frame #14: 0x000000010ab52880 CoreFoundation
__CFRunLoopDoObservers + 368 кадр # 15: 0x000000010ab480d3 CoreFoundation__CFRunLoopRun + 1123 frame #16: 0x000000010ab47a06 CoreFoundation
CFRunLoopRunSpecific + 470 кадров # 17: 0x000000010e9e9abf GraphicsServicesGSEventRunModal + 161 frame #18: 0x000000010bb39cf8 UIKit
UIApplicationMain + 1282 frame # 19: 0x000000010a0e6a5d GPS-трекtop_level_code + 77 at AppDelegate.swift:36 frame #20: 0x000000010a0e6a9a GPS Track
main + 42 в AppDelegate.swift:0 кадр #21: 0x000000010d2e7145 libdyld.dylib`start + 1 (lldb)
8 ответов
Я проследил это дальше: проблема возникает только при использовании пользовательских классов объектов для сущностей. Пример:
// User class, defined in User.swift
class User: NSManagedObject {
@NSManaged var name: String
@NSManaged var firstname: String
}
// --------------
// code somewhere else
let users = moc.executeFetchRequest(fetchRequest, error: &error)
for object in users {
let user = object as User // <-- breakpoint fired here
println(user.name)
}
}
РЕШЕНИЕ:
Нужно сделать класс пользовательских объектов видимым для Objective C, используя директиву @objc:
// User class, defined in User.swift
@objc(User) // <-- required!
class User: NSManagedObject {
@NSManaged var name: String
@NSManaged var firstname: String
}
Спасибо всем за помощь!
Хотя приведенные выше ответы все технически верны
@zisoft прав, однако, если вы используете пользовательские классы NSManagedObject, вы всегда должны использовать @objc(User), а не только из-за этой точки останова.
@Zaph может также работать, так как вы по сути не слушаете, и если это действительно ошибка, она должна остановить его появление
Однако вы все равно можете достичь такого рода точки останова, если вы не проверяете тип. Я подозреваю, что это точка останова в бета-версии 4, но в следующей бета-версии это будет крах.
Я решил эту проблему в своем коде, когда пытался вернуть управляемый объект, полученный от insertNewObjectForEntityForName, в виде AnyObject, а затем сказал, что в качестве myclass я использовал его. Хорошо, поскольку я знал, что это был мой класс. но на самом деле следовало сделать что-то вроде этого
func createMyEntity() -> MyClass{
if let entity : MyClass = NSEntityDescription.insertNewObjectForEntityForName("MyClass", inManagedObjectContext: self.managedObjectContext) as? MyClass
{
return entity;
}
return nil;
}
Очевидно, это только один пример, но если вы достигаете точки останова в других местах, то, надеюсь, это хорошая ссылка.
Несмотря на это, это может быть просто ошибкой в бета-версии xcode, но в любом случае это безопаснее.
Обновление - оно также проверяет, совпадает ли имя вашего класса модели данных, как это происходит позже, посредством предупреждения здесь, и это также может быть причиной того, что была достигнута точка останова.
У вас установлена точка останова All Exception?
Вопреки лучшим практикам Apple, CoreData использует исключения в нормальном потоке управления.
Если вы добавите точки останова исключения, вы можете сломать в CoreData. Решение состоит в том, чтобы удалить или отключить точку останова исключения.
Я исправил свою версию этой проблемы на основе информации в https://devforums.apple.com/message/1016337
- сделать
NSManagedObject
класс и его соответствующие свойстваpublic
- не включайте его исходный файл в источники компиляции цели теста
- импортировать цель приложения в тестовый файл - например,
import MyApp
вMyClassTests.swift
В ваших основных данных *.xcdatamodeld
файл, префикс имени класса вашей сущности с именем вашего приложения. Когда вы закончите, это должно выглядеть примерно так:
Следующее помогло мне! Если я отменил одну из этих настроек, снова появится ошибка точки останова!
Вы должны установить для вашей Entity-Model в вашем *Model.xcdatamodeld в свойстве "Class" тот же пример имени: Name =Chat Class=Chat
Вы должны добавить код @objc(yourClass) над своим классом
Фотографии 1:
Для тех, кто использует Xcode 6.2
- Делать
@objc
изменения в вашем классе, т.е.@objc(className)
- Далее перейдите к
*.xcdatamodeld
->Configurations
(По умолчанию, если ничего не указано) -> добавить класс против сущности
Спасибо последнее помогло!!!
- сделать класс, производный от NSManagedObject, и его соответствующие свойства общедоступными
- не включайте его исходный файл в источники компиляции цели теста
- импортировать цель приложения в тестовый файл - например, импортировать MyApp в MyClassTests.swift