segueing 时的核心数据错误:无法在 NSManagedObject 类上调用指定的初始化程序
Posted
技术标签:
【中文标题】segueing 时的核心数据错误:无法在 NSManagedObject 类上调用指定的初始化程序【英文标题】:Core Data Error when segueing: Failed to call designated initializer on NSManagedObject class 【发布时间】:2017-12-13 23:03:06 【问题描述】:当点击 mapView 上的 pin 时,我有一个视图控制器会连接到另一个视图控制器。 “Pin”是一个 NSManagedObject,它在发送到第二个视图控制器(其中一个函数用实际图像填充它)之前填充了纬度和经度。
在我的 didSelect 函数完成后和调用 performSegue 函数之前,我收到错误“CoreData:错误:无法在 NSManagedObject 类 'Pin' 上调用指定的初始化程序”。
@nonobjc public class func fetchRequest() -> NSFetchRequest<Pin>
return NSFetchRequest<Pin>(entityName: "Pin")
@NSManaged public var latitude: Double
@NSManaged public var longitude: Double
@NSManaged public var images: NSSet?
这是类:
convenience init(latitude: Double, longitude: Double, context: NSManagedObjectContext)
if let entity = NSEntityDescription.entity(forEntityName: "Pin", in: context)
self.init(entity: entity, insertInto: context)
self.latitude = latitude
self.longitude = longitude
else
fatalError("Unable to find entity name")
我尝试将 pin 声明为可选并强制使用“!”声明它。这两个选项都不起作用。根据我在网上学习和阅读的许多帖子,我需要使用指定的初始化程序来初始化 pin 变量。这是我在视图控制器类顶部的尝试,但它也不起作用。
var pin = Pin.init(entity: NSEntityDescription.entity(forEntityName: "Pin", in: CoreDataStack.sharedInstance().context)!, insertInto: CoreDataStack.sharedInstance().context)
创建图钉:
// Create the annotation
let touchPoint = gestureRecognizer.location(in: mapView)
let newCoordinate = self.mapView.convert(touchPoint, toCoordinateFrom:self.mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinate
pin = Pin(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude, context: CoreDataStack.sharedInstance().context)
let pinAnnotation = PinAnnotation(objectID: pin.objectID, title: nil, subtitle: nil, coordinate: annotation.coordinate)
// Add the annotation
mapView.addAnnotation(pinAnnotation)
CoreDataStack.sharedInstance().saveContext()
在 didSelect 中选择引脚:
do
let pinAnnotation = view.annotation as! PinAnnotation
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Pin")
let predicate = NSPredicate(format: "latitude == %@ AND longitude == %@", argumentArray: [pinAnnotation.coordinate.latitude, pinAnnotation.coordinate.longitude])
fetchRequest.predicate = predicate
let pins = try CoreDataStack.sharedInstance().context.fetch(fetchRequest) as? [Pin]
pin = pins![0]
catch let error as NSError
print("failed to get pin by object id")
print(error.localizedDescription)
return
self.performSegue(withIdentifier: "collectionViewSegue", sender: self)
...并执行转场:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "collectionViewSegue"
let controller = segue.destination as! CollectionViewController
print("CoreDataStack context in segue= \(CoreDataStack.sharedInstance().context)")
controller.selectedPin = pin
if let images = pin.images?.allObjects as? [Images]
controller.photos = images
print("PrepareForSegue pin properties are: \n latitude: \(pin.latitude) \n longitude: \(pin.longitude)")
我错过了什么?
【问题讨论】:
【参考方案1】:我通过在课程开始时将变量声明设为可选来解决了这个问题:
var selectedPin: Pin?
...并在我的长按手势识别器功能中进行不同的初始化:
@objc func handleLongPress(_ gestureRecognizer : UIGestureRecognizer)
if gestureRecognizer.state != .began return
print("Tap gesture recognized")
// Create the annotation
let touchPoint = gestureRecognizer.location(in: mapView)
let newCoordinate = self.mapView.convert(touchPoint, toCoordinateFrom:self.mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinate
// Initialize NSManagedObject 'Pin' with properties
selectedPin = Pin(context: CoreDataStack.sharedInstance().context)
selectedPin?.latitude = annotation.coordinate.latitude
selectedPin?.longitude = annotation.coordinate.longitude
if let selectedPin = selectedPin
let pinAnnotation = PinAnnotation(objectID: selectedPin.objectID, title: nil, subtitle: nil, coordinate: annotation.coordinate)
// Add the annotation
mapView.addAnnotation(pinAnnotation)
CoreDataStack.sharedInstance().saveContext()
print("This is what the ole save looks like: \(CoreDataStack.sharedInstance().context)")
【讨论】:
以上是关于segueing 时的核心数据错误:无法在 NSManagedObject 类上调用指定的初始化程序的主要内容,如果未能解决你的问题,请参考以下文章
iOS8 UITableView 和 Cell - 自动布局高度 - 触摸和执行 segue 时的移位/垂直偏移错误