我的应用程序应该删除名为" Pin"的NSManagedObjects。包含以下属性:
@NSManaged public var imageData: NSData?
@NSManaged public var imageURL: String?
@NSManaged public var title: String?
@NSManaged public var pin: Pin?
...但是,我收到了错误:
"NSLocalizedDescription": The operation couldn’t be completed. (Cocoa error 1570.), "NSValidationErrorKey": imageData]
将imageData属性设置为可选属性,因此我对Core Data无法删除的原因感到有些困惑。
这是执行删除的didSelect函数:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if !isEditing {
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]
selectedPin = 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)
} else {
mapView.removeAnnotation(view.annotation!)
if let selectedPin = selectedPin {
CoreDataStack.sharedInstance().context.delete(selectedPin)
}
CoreDataStack.sharedInstance().saveContext()
return
}
}
我的引脚类:
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属性扩展:
extension 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?
}
...并且Pin NSManagedObject的实例化:
@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)
mapView.addAnnotation(pinAnnotation)
FlickrClient.sharedInstance().getImagesFromFlickr(pin: selectedPin, context: CoreDataStack.sharedInstance().context, page: 1) { (images, error) in
guard error == nil else {
print("There was an error get images objects")
return
}
if let images = images {
for image in images {
image.pin = selectedPin
}
performUIUpdatesOnMain {
self.images = images
CoreDataStack.sharedInstance().saveContext()
}
}
}
}
print("The context has changes: \(CoreDataStack.sharedInstance().context.hasChanges)")
CoreDataStack.sharedInstance().saveContext()
}
建议?
答案 0 :(得分:0)
我通过删除保存功能的一个实例解决了这个问题:
CoreDataStack.sharedInstance().saveContext()
在我的handleLongPress函数的底部。在将视图分配给视图控制器中的局部变量之前调用此方法。 saveContext()只需要在performUIUpdatesOnMain(我的GCD异步方法)函数中调用。
同一个类中的代码也是不必要的:
for image in images {
image.pin = selectedPin
}