핵심 데이터 모델을 업데이트합니다.아, 아니오.

13315 단어 macoscoredataios
만약 네가 CoreData를 연구하는 데 시간을 쓴다면, 너는 의견이 있을 것이다.
개인적으로 좋아해요.그것은 간단한 지구층으로 도형 모델링과 관계 해석을 가지고 있다.현재NSPersistentContainer API는 몇 줄의 코드만으로 가능합니다.자신도 좋아한다고 분명히 밝힌 이 팀은 해마다 새로운 발전을 가져올 것이다.
CoreData가 데이터베이스가 아님을 알아야 합니다.기본 모드는 SQLite 파일에 데이터를 저장하는 것입니다. 이것은 단지 세부 사항일 뿐입니다.CoreData도 관계 데이터베이스가 아니므로 관계 데이터베이스로 보지 마십시오.
가장 경험이 많은 개발자라도 두려워하는 활동은 당신의 것을 업그레이드하는 것입니다SQLite.간단한 변경 (예를 들어 속성 추가) 은 매우 쉽지만, 더욱 복잡한 변경 (예를 들어 관계 수정) 은 어려울 수 있습니다. 특히 여러 모델 버전을 처리해야 할 때.아무도 클라이언트 데이터를 잃어버리기를 원하지 않는다.
실제로 자동 모형 업그레이드 시스템을 사용할 때 지속적인 저장소에서 업그레이드 전환을 사용하는데 이것은 어느 정도 간단하고 투명하다.
let container = NSPersistentContainer(name: "Unicorn")
let url = //url to store file
let store = NSPersistentStoreDescription(url: url)
store.shouldMigrateStoreAutomatically = true
store.shouldInferMappingModelAutomatically = true
container.persistentStoreDescriptions = [store]
container.loadPersistentStores { (storedesc, error) in
     //do data dependant setup
}
xcdatamodel & shouldMigrateStoreAutomaticallyshouldInferMappingModelAutomatically 로 설정하고 하루를 계속할 수 있습니다.
어떻게 새로운 true 버전을 도입하지 않고 모델을 업데이트합니까?만약 당신이 미리 준비를 한다면, 당신은 무서운 모델의 업그레이드를 피하기 위해 실체에 약간의 연동 공간을 증가시킬 수 있다.
사용xcdatamodel™ 기교실체에 위치를 추가하여 범용 Bucket of Goo 을 저장하고 이 사전에 합성 속성을 저장합니다.이것은 결코 완전한 반모드가 아니지만, 직접적인 원가와 기술 채무 형식의 원가가 존재하기 때문에 확장성이 강하지 않다.그러나 이것은 당신을 일시적인 곤경에서 벗어나게 할 수도 있다.
먼저 Dictionary 유형의 metadataEntity 속성을 추가합니다.유형 Data 을 사용하지 않으려는 이유도 알 수 있습니다.

자동으로 생성된 클래스 파일 또는 자신을 위한 클래스 파일은 다음과 유사합니다
class Thing: NSManagedObject {

    @NSManaged var name: String?
    @NSManaged var index: Int16
    @NSManaged var metadata1: String?
    @NSManaged var metadata2: Data?
}
모든 속성은 String 로 표시되며 Objective-C가 실행될 때와 KVO 메커니즘에 연결됩니다.
다음은 합성 사전에 대한 간단한 접근을 원합니다.
var metadataDictionaryString: SwiftDict {
    get {
        let string = metadata1
        if let dict = string?.propertyList() as? SwiftDict {
            return dict
        }
        return [:]
    }
    set {
        let string = (newValue as NSDictionary).description
        metadata1 = string
    }
}
이 코드 세그먼트를 사용하지 마십시오.내가 과거에 얼마나 어리석은 사람이었는지 보여주기 위해서야.그것은 @NSManaged, description, plist, NSStringNSDictionary 생성에 유효하다는 사실에 의존한다.상황이 더 이상 이렇지 않다. NSArray 같은 유형은 운행할 때 붕괴될 것이다.
합성 속성을 실현하는 방법은 Data을 삽 종류에 사용하고 Data를 왕복하는 것이다.
var metadataDictionaryData: SwiftDict {
    get {
        if let data = metadata2 {
            do {
                let dict = try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? SwiftDict
                return dict ?? [:]
            }
            catch {
                print("plist decode err - ",error)
            }
        }
        return [:]
    }
    set {
        do {
            let data = try PropertyListSerialization.data(fromPropertyList: newValue, format: .binary, options: 0)
            metadata2 = data
        }
        catch {
            print("plist encode err - ",error)
        }
    }
}
다음 단계는 새로운 의외의 속성을 합성하는 것입니다.우리는 그것을 PropertyListSerialization 라고 부른다.
extension Thing {

    @objc var extendedName: String? {
        get {
            return metadataDictionaryData["extendedName"] as? String
        }
        set {
            metadataDictionaryData["extendedName"] = newValue
        }
    }

}
현재 모델에 연소extendedName대가 필요 없는 새로운 속성이 있습니다.

비용은 얼마입니까?


비용은 다음과 같습니다.
  • 사용 시간.모든 요청은 xcdatamodelblob에서 카드를 씻거나 씻어야 합니다.
  • CPU 주기 = = 전력 소비량.
  • 을(를) 통해 액세스할 수 없거나 검색할 수 없습니다.
  • 우선적으로 정확하게 조작하지 않아 발생한 기술채무일 수 있다.
  • macOS에서 간단한 테스트를 하면 보실 수 있습니다.
    엔티티Data의 속성NSFetchRequest에 액세스하고 업데이트합니다.
    0.00485 s to add 1000 items
    0.00513 s to update 1000 items
    0.00657 s to read 1000 items
    
    액세스 및 업데이트name, 이 속성은 Thing 에서 지원하는 합성 속성입니다.
    0.02022 s to add extended 1000 items
    0.03116 s to update extended 1000 items
    0.01254 s to read extended 1000 items
    
  • Add 작업의 비용은 약 5배입니다.
  • 업데이트의 약 6배가 더 비싸다.
  • Read는 약 2배 비싸다.
  • 너는 이런 상황을 완화시킬 수 있니?


    쓰기/읽기가 많은 경우 캐시를 사용할 수 있습니다.그러나 이것은 확실히 메모리 사용량을 증가시킬 것이다.
    fileprivate var metadata2Cache: SwiftDict?
    
    var metadataDictionaryData: SwiftDict {
        get {
            if let cache = metadata2Cache {
                return cache
            }
            if let data = metadata2 {
                ...
            }
            return [:]
    
        }
        set {
            do {
                let data = ...
                metadata2 = data
                metadata2Cache = nil
            }
            catch {
                print("plist encode err - ",error)
            }
        }
    }
    
    우선 extendedName 캐시를 불러오고 metadata2 캐시를 태워버리십시오.
    차이를 보다.
    **0.02022 s to add extended 1000 items
    **0.03116 s to update extended 1000 items
    **0.01254 s to read extended 1000 items
    **0.00972 s to read extended 1000 items
    **0.00840 s to read extended 1000 items
    
    첫 번째 읽기에는 디코딩getblob이 필요하지만 후속 읽기는 캐시에서 가져옵니다. 본 컴퓨터의 속성보다 약 1.25배 높습니다.

    결론


    합성 버전에 속성을 덤프하여 모델 업그레이드를 피할 수 있지만 처리 비용에 큰 단점이 있습니다.이런 기술은 성능이 민감한 순환로에 적용되지 않는다.
    너는 아마도 이런 기교로 자신을 곤경에서 파낼 수 있을 것이다. 그러나 그것을 장기적인 확장 전략으로 여기지 마라.새 모델 세대를 생성합니다.

    좋은 웹페이지 즐겨찾기