2016-07-31 3 views
2

크기가 1MB 인 이미지가 < 인 테이블보기가 있습니다. 필자는 스크롤 할 때 서버에서 각 이미지를 가져 와서 이미 캐시되지 않은 경우 CoreData에 저장합니다. 나는 천천히 스크롤하면 여기 'cellForRowAtIndexPath'에서 CoreData로 저장하면 스크롤 할 때 오류가 발생합니다.

는 잘 작동

// MARK: - Save Image to Core Data 

func saveImageToCoreData(url: String,imageData: NSData) { 
    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate { 
     if let managedContext = appDelegate.managedObjectContext as? NSManagedObjectContext { 

      let privateMoc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) 
      privateMoc.parentContext = managedContext 

      let entity = NSEntityDescription.entityForName("Images", 
                  inManagedObjectContext: privateMoc) 
      let options = NSManagedObject(entity: entity!, 
              insertIntoManagedObjectContext: privateMoc) 

      options.setValue(url, forKey: "url") 
      options.setValue(imageData, forKey: "imageData") 

      privateMoc.performBlock({ 


       do { 
        try privateMoc.save() 
        print("Successfuly Saved an Image to Core Data.") 
        do { 
         try managedContext.save() 
        } catch { 

        } 
       } catch { 
        // Failed to save 
       } 

      }) 
     } 
    } 
} 

... 내가 핵심 데이터에 각각의 이미지를 저장하기 위해 사용하는 기능입니다. 그러나이 함수를 빠르게 스크롤하여 'cellForRowAtIndexPath'를 여러 번 호출하면 오류 및 충돌이 발생합니다.

오류 예 : CoreData: error: (1555) UNIQUE constraint failed: ZIMAGES.Z_PK

내 저장 기능이 잘못인가? 아니면 저장 기능을 수행하기 위해 한 번에 많은 스레드를 설정하는 데 문제가 있습니까?

모든 아이디어를 높이 평가합니다! 감사!

답변

1

저장 기능에 몇 가지 문제점이 있습니다.
1. 각 이미지에 대해 개인 대기열 컨텍스트를 작성하는 것이 좋지 않습니다. 더 좋은 방법은 단일 개인 큐 컨텍스트를 만들고 모든 이미지를 저장하는 데 사용하는 것입니다.
2. 테이블 뷰를 위아래로 스크롤 할 때이 위임 함수가 여러 번 호출되므로 cellForRowAtIndexPath에이 이미지 저장 함수를 호출하지 마십시오. 다운로드 이미지 완료 콜백과 같이 다른 곳에서 해보십시오.
3. CoreData는 스레드로부터 안전하지 않으므로 주 스레드가 아닌 사적인 컨텍스트의 스레드에 새 이미지를 삽입해야합니다. 그래서 당신은이 작업을 수행해야한다 :

privateMoc.performBlock({ 
    let entity = NSEntityDescription.entityForName("Images", inManagedObjectContext: privateMoc) 
    let options = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: privateMoc) 
    options.setValue(url, forKey: "url") 
    options.setValue(imageData, forKey: "imageData") 
    do { 
     try privateMoc.save() 
     print("Successfuly Saved an Image to Core Data.") 
     do { 
      try managedContext.save() 
     } catch { 
     } 
    } catch { 
     // Failed to save 
    } 
}) 

당신이이 세 가지 수정을 한 후, 문제가 해결되어야한다 믿습니다.

0

SDWebImage를 사용할 수 있습니다.

관련 문제