【问题标题】:(Cocoa error 1570.), "NSValidationErrorKey" error(可可错误 1570。),“NSValidationErrorKey”错误
【发布时间】:2017-12-19 02:57:01
【问题描述】:

我的应用应该删除名为“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")
    }
}

引脚属性扩展:

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()

}

建议?

【问题讨论】:

  • 您是否尝试在删除行设置断点并检查 selectedPin 是否填充了 imageData
  • @AjayReddy 我确实这样做了。事实上,我重置了所有内容和设置,以确保我首先清除了所有现有数据。对于我在编辑模式下点击删除的第一个图钉,它工作正常。但是,在我尝试删除第二个引脚时 selectedPin 的内容是 -via print 语句: ( (entity: Pin; id: 0xd000000000240000 ; 数据:)
  • @AjayReddy 有什么想法吗?
  • 看起来你的“Pin”中的数据没有被正确填充......当你用值实例化对象“Pin”时......你能确保你是填充“Pin”中的所有变量...您可以在“Pin”类的 init() 方法中检查这一点
  • 我已经编辑了这篇文章,以展示我如何实例化 NSManagedObject “Pin”,以及它的类和扩展。在尝试完成这项工作时,我还收到了一个可能相关的单独错误:“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'非法尝试在不同上下文中的对象之间建立关系'pin'”。我的 NSManagedObjectContext 是共享实例,所以我不确定这是怎么发生的。感谢您的指导。

标签: swift cocoa core-data mkmapview nsmanagedobject


【解决方案1】:

我通过删除我的保存功能的一个实例解决了这个问题:

CoreDataStack.sharedInstance().saveContext()

在我的 handleLongPress 函数的底部。这是在将图像分配给我的视图控制器中的局部变量之前调用的。 saveContext() 只需要在 performUIUpdatesOnMain(我的 GCD 异步方法)函数中调用。

同一个类中的这段代码也是不必要的:

for image in images {
                image.pin = selectedPin
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-13
    • 2011-10-03
    • 2013-10-27
    • 2011-06-19
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多