由 NSFetchedResultsController 处理的 UICollectionView 单元格不重新填充图像

UICollectionView Cells Handled by NSFetchedResultsController not Repopulating Images

在过去的几天里,我一直在尝试通过在集合视图存在的视图中按下 'newCollection' 按钮,用新的数据图像填充 UICollectionView。我可以在我的控制台中看到正在下载图像数据,并且我可以在离开视图后看到填充的 CV 单元格,然后 return。知道为什么集合视图单元格没有实时更新吗?

这是我正在处理的内容:

https://github.com/tdangles81/Virtual-Tourist/tree/detail-view

@IBAction func newCollectionBtn(sender: AnyObject) {
    getNewCollection()
}

func getNewCollection(){
    if let newFetch = self.fetchedResultsController.fetchedObjects{
        for object in newFetch{
            let newImg = object as! ImgModel
            self.sharedContext.deleteObject(newImg)
        }
    }
    FlickrRequestClient.sharedInstance().getNewGeoImgs(selectedPin)
}

var sharedContext: NSManagedObjectContext {
    return CoreDataStack.sharedInstance().managedObjectContext
}

func saveContext(){
    return CoreDataStack.sharedInstance().saveContext()
}

lazy var fetchedResultsController: NSFetchedResultsController = {

    let fetchRequest = NSFetchRequest(entityName: "Image")
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
    fetchRequest.predicate = NSPredicate(format: "pin == %@", self.selectedPin)

    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
                                                              managedObjectContext: self.sharedContext,
                                                              sectionNameKeyPath: nil, cacheName: nil)
    return fetchedResultsController
}()

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin") as? MKPinAnnotationView
    if pinView == nil{
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
    }else{
        pinView?.annotation = annotation
    }
    return pinView
    }


func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return fetchedResultsController.sections?.count ?? 0
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    let sectionInfo = self.fetchedResultsController.sections![section]
    print(sectionInfo.numberOfObjects)
    return sectionInfo.numberOfObjects
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DetailCell", forIndexPath: indexPath) as! ImageCollectionCell
    let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel

    configureUI(cell, image: image, atIndexPath: indexPath)
    return cell
}

func configureUI(cell: ImageCollectionCell, image: ImgModel, atIndexPath indexPath: NSIndexPath) {

    if image.image != nil{
        image.loadUpdateHandler = nil
        cell.flickrImageView.image = image.image!
        print("Image.image \(image.image!)")
        self.saveContext()
    }else{
        image.loadUpdateHandler = {[unowned self] () -> Void in
        dispatch_async(dispatch_get_main_queue(), {
        self.collectionView.reloadData()
            })
        }
        cell.flickrImageView.image = image.image
    }
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
    if collectionView.cellForItemAtIndexPath(indexPath) != nil {
        let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel
        print(image)
    }
}

func controllerWillChangeContent(controller: NSFetchedResultsController) {

    insertedIndex = [NSIndexPath]()
    updatedIndex = [NSIndexPath]()
    deletedIndex = [NSIndexPath]()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:
        insertedIndex.append(newIndexPath!)
    case .Update:
        updatedIndex.append(indexPath!)
    case .Move:
        print("Surprise!")
    case .Delete:
        deletedIndex.append(indexPath!)
    }
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    collectionView.performBatchUpdates({() -> Void in
        for indexPath in self.insertedIndex {
            self.collectionView.insertItemsAtIndexPaths([indexPath])
        }
        for indexPath in self.updatedIndex {
            self.collectionView.reloadItemsAtIndexPaths([indexPath])
        }
        for indexPath in self.deletedIndex {
            self.collectionView.deleteItemsAtIndexPaths([indexPath])
        }
        },completion: nil)

}

func addSpinner(cellView: UICollectionViewCell, activityBool: Bool){

    let activitySpinner =      UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
    activitySpinner.center = cellView.center
    activitySpinner.color = UIColor.whiteColor()
    activitySpinner.startAnimating()

    if activityBool == true{
        activitySpinner.startAnimating()
        cellView.addSubview(activitySpinner)
    }else if activityBool == false{
        activitySpinner.stopAnimating()
        cellView.willRemoveSubview(activitySpinner)
    }
}

func removeSpinner(){

}

}

我在 NSFetchedResultsController 行为中遇到了问题。如果在获取请求时设置了 NSPredicate,则不会调用委托方法。

尝试去掉谓词,看看你是否也有这个问题。

我正在尝试查看它是否是 Xcode 中的错误,或者是与故障相关的一些未处理的错误,或者 NSFetchedResultsController class 中是否使用了新的查询令牌系统,我们需要做点什么。