簡體   English   中英

NSBatchUpdateRequest沒有保存Transformable屬性

[英]NSBatchUpdateRequest not saving Transformable attribute

我有一個實體( TestEntity ),其中包含一個包含對象( MyObjectClass )的“ Transformable”屬性。 初始加載時,可變形對象正確保存; 初始化如下:

TestEntity *test = (TestEntity *)[NSEntityDescription insertNewObjectForEntityForName:ENTITY[<Int>] inManagedObjectContext:temporaryContext];
test.transformableAttr = [[MyObjectClass alloc] initWithObject:obj];

但是,當我獲取一個對象(使用NSDictionaryResultType作為字典來獲取)並更新其“ Transformable”屬性時,

MyObjectClass *my_obj = ....
dict[@"transformableAttr"] = my_obj

它可以成功保存,但是當我再次獲取它時,“ Transformable”屬性將nil

現在,這僅在“ NSBatchUpdateRequest”中發生,因為當我使用MOC保存時

TestEntity *test = ....
test.transformableAttr = updated_object

它保存成功,再次獲取時我可以訪問更新的屬性。

誰能解釋一下? 這是否意味着NSBatchUpdateRequest不可轉換?

我的NSBatchUpdateRequest代碼:

[context performBlock:^{
    NSError *requestError               = nil;
    NSBatchUpdateRequest *batchRequest  = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:entity];
    batchRequest.resultType             = NSUpdatedObjectIDsResultType;
    batchRequest.propertiesToUpdate     = properties;
    NSBatchUpdateResult *result         = nil;
    SET_IF_NOT_NIL(batchRequest.predicate, predicate)

    @try {
        result = (NSBatchUpdateResult *)[context executeRequest:batchRequest error:&requestError];
        if (requestError != nil){
            // @throw
        }

        if ([result.result respondsToSelector:@selector(count)]){
            __block NSInteger counter = [result.result count];

            if (counter > 0){
                [managedObjectContext performBlock:^{

                    for(NSManagedObjectID *objectID in result.result){
                        NSError *faultError = nil;
                        NSManagedObject *object = [managedObjectContext existingObjectWithID:objectID error:&faultError];

                        if (object && faultError == nil) {
                            [managedObjectContext refreshObject:object mergeChanges:YES];
                        }

                        counter--;
                        if (counter <= 0) {
                            // complete
                        }
                        else{
                            // Wait.
                        }
                    }
                }];
            }
            else{
                // No Changes
            }
        }
        else {
            // No Changes
        }
    }
    @catch (NSException *exception) {
        @throw;
    }
}];

該文檔似乎並未指出這種特殊情況,但是對於它不起作用我並不感到驚訝。 NSBatchUpdateRequest描述為[重點]:

請求Core Data在不將任何數據加載到內存的情況下對持久性存儲中的數據進行批處理更新。

可轉換對象通過在內存中的Data進行轉換來工作。 如果您的類符合NSCoding ,則編碼/解碼將在內存中進行,因為SQLite不了解NSCoding或您的類。

您原來的分配工作,因為核心數據的值轉換transformableAttrData在內存中,然后保存字節的Data持久性存儲。 在批處理更新中,對象沒有加載到內存中,因此轉換無法運行,因此更新無法按預期工作。

令人失望的是,Core Data並沒有更清楚地說明這一點。 在Xcode控制台中查看是否會警告您。 如果不行,請向Apple提交錯誤,因為盡管我不希望這樣做有效,但使其無聲地失敗也不是一件好事。

如果要使用批處理更新,則必須在運行更新之前轉換代碼中的值。 我不確定100%如何運作,但如果您的價值符合NSCoding您將從

let transformedData: Data = NSKeyedArchiver.archivedData(withRootObject:transformableAttr)

那我不知道該怎么辦。 您也許可以將transformedData用作新值。 或者,您可能必須訪問其字節並以某種方式使用它們-也許使用withUnsafeBytes(_:) 您可能會遇到麻煩,因為transformableAttr不是Data ,因此可能會變得凌亂。 似乎批處理更新的設計不適合與可轉換對象一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM