Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSBatchUpdateRequest未保存可转换属性_Ios_Objective C_Core Data_Nsbatchdeleterequest_Nsbatchupdaterequest - Fatal编程技术网

Ios NSBatchUpdateRequest未保存可转换属性

Ios NSBatchUpdateRequest未保存可转换属性,ios,objective-c,core-data,nsbatchdeleterequest,nsbatchupdaterequest,Ios,Objective C,Core Data,Nsbatchdeleterequest,Nsbatchupdaterequest,我有一个实体(TestEntity),它包含一个“可转换”属性,该属性保存一个对象(MyObjectClass)。在初始负载时,可转换存储正确;草签如下: TestEntity *test = (TestEntity *)[NSEntityDescription insertNewObjectForEntityForName:ENTITY[<Int>] inManagedObjectContext:temporaryContext]; test.transformableAttr =

我有一个实体(
TestEntity
),它包含一个“可转换”属性,该属性保存一个对象(
MyObjectClass
)。在初始负载时,可转换存储正确;草签如下:

TestEntity *test = (TestEntity *)[NSEntityDescription insertNewObjectForEntityForName:ENTITY[<Int>] inManagedObjectContext:temporaryContext];
test.transformableAttr = [[MyObjectClass alloc] initWithObject: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;
    }
}];
[上下文执行锁:^{
NSError*requestError=nil;
NSBatchUpdateRequest*batchRequest=[NSBatchUpdateRequest batchUpdateRequestWithEntityName:entity];
batchRequest.resultType=nsUpdatedObjectdResultType;
batchRequest.propertiesToUpdate=属性;
NSBatchUpdateResult*结果=nil;
如果不是,则设置(batchRequest.predicate,predicate)
@试一试{
结果=(NSBatchUpdateResult*)[context executeRequest:batchRequest错误:&requestError];
if(requestError!=nil){
//@扔
}
if([result.respondsToSelector:@selector(count)]){
__块NSInteger计数器=[result.result count];
如果(计数器>0){
[managedObjectContext执行锁:^{
for(result.result中的NSManagedObjectID*objectID){
NSError*faultError=nil;
NSManagedObject*object=[managedObjectContext existingObjectWithID:objectID错误:&faultError];
if(object&&faultError==nil){
[managedObjectContext刷新对象:对象合并更改:是];
}
计数器--;

如果(counter文档似乎没有指出这一特定场景,但我并不奇怪它不起作用。
NSBatchUpdateRequest
被描述为[强调我的]:

对Core Data的一种请求,在不将任何数据加载到内存的情况下,对持久存储中的数据进行批更新

可转换文件通过转换内存中的
数据来工作。如果您的类符合
NSCoding
,则编码/解码发生在内存中,因为SQLite不知道
NSCoding
或您的类

原始赋值之所以有效,是因为核心数据将
transformableAttr
的值转换为内存中的
数据
,然后将
数据
的字节保存到持久存储。在批处理更新中,对象未加载到内存中,因此转换无法运行,因此更新无法按预期工作

令人失望的是,核心数据并没有让这一点变得更清晰。查看Xcode控制台,看看它是否警告您这一点。如果没有,请向苹果公司提交一个bug,因为尽管我不认为这会起作用,但它也不利于无声地失败

如果要使用批处理更新,则必须在运行更新之前转换代码中的值。我不能100%确定这将如何工作,但如果您的值符合
NSCoding
的要求,您将从

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

我不确定您要做什么。您可能可以使用
transformedData
作为新值。或者您可能必须访问其字节并以某种方式使用它们--可能使用
with unsafebytes(:)
。您可能会遇到麻烦,因为
transformableAttr
不是一个
数据,所以它可能会变得凌乱。看来批量更新的设计不适合transformables。

感谢您的回答,它确实澄清了我的问题。我确实使用了NSData,这两种情况都适用,但随着时间的推移,数据变得太大和太复杂对性能造成影响。不幸的是,日志在NSBatchUpdateRequest上没有显示任何内容,并且将向apple提交一个错误。我能够使用[NSKeyedArchivedDataWithRootObject:@“MyTestString”]作为propertiesToEdit字典中的值,它对我的可转换属性起作用。我无法说明NSString以外的值如何工作(没有测试)。
let transformedData: Data = NSKeyedArchiver.archivedData(withRootObject:transformableAttr)