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)