代码之家  ›  专栏  ›  技术社区  ›  carok

如何将nsmanagedObjects的nsarray转换为nsdata

  •  2
  • carok  · 技术社区  · 15 年前

    我不熟悉目标C,想知道是否有人能帮助我。

    我使用一个带有sqlite数据库的核心数据来保存具有名称和score属性的简单概要文件对象(两者都是nsstring类型)。

    我要做的是获取配置文件并将其存储在NSData对象中,请参见下面的代码:

                NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
                NSEntityDescription *entity = [NSEntityDescription entityForName:@"GamerProfile" inManagedObjectContext:managedObjectContext];
                [fetchRequest setEntity:entity];
    
                NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
                NSArray *sortDecriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
                [fetchRequest setSortDescriptors:sortDecriptors];
    
                [sortDescriptor release];
                [sortDecriptors release];           
    
                NSError *error;
                NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    
                NSData *data = [NSKeyedArchiver archivedDataWithRootObject:items];
    
                [self SendData:data];
                [fetchRequest release];
    

    当我运行代码时,我收到错误“由于未捕获的异常而终止应用程序”nsInvalidargumEntexception“,原因:'***-[GamerProfile EncodeWithCoder:]:无法识别的选择器发送到实例0x3f4b530'”

    我想我必须在我的核心数据nsmanagedObject对象(gamerprofile)中添加一个encodewithcoderclass,但我不知道该怎么做,即使在阅读了 documentation ,我的尝试如下。我不确定我是否按照正确的方式来处理,因为会收到一条警告:“nsmanagedObject”可能不会响应“-encodewithcoder”。

    如果有人能给我指明正确的方向,我会非常非常感激的!!

    谢谢

    C

    这是我的gamerprofile(coredatansmanagedObject对象)的代码,我试图添加一个encodewithcoder方法…

    头文件

    #import <CoreData/CoreData.h>
    
    
    @interface GamerProfile :  NSManagedObject <NSCoding>
    {
    }
    
    @property (nonatomic, retain) NSString * GamerScore;
    @property (nonatomic, retain) NSString * Name;
    
    - (void)encodeWithCoder:(NSCoder *)coder;
    
    
    @end
    

    代码文件

    #import "GamerProfile.h"
    
    
    @implementation GamerProfile 
    
    @dynamic GamerScore;
    @dynamic Name;
    
    - (void)encodeWithCoder:(NSCoder *)coder {
    
        [super encodeWithCoder:coder];
    
        [coder encodeObject:GamerScore forKey:@"GamerScore"];
        [coder encodeObject:Name forKey:@"Name"];
    
    
    
    }
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Community CDub    8 年前

    nsmanagedObject和nscoding确实不能很好地配合使用。考虑 this answer to a similar question 背景和可能的解决方案。

        2
  •  4
  •   Pat    15 年前

    我要用这个。方法如下。

    首先创建一个NSValueTransformer,如下所示:

    阵列数据转换器.h

    @interface ArrayToDataTransformer : NSValueTransformer {
    
    }
    
    @end
    

    阵列数据转换器.m

    导入“arraytodataTransformer.h”

    @implementation ArrayToDataTransformer
    
    + (BOOL)allowsReverseTransformation {
        return YES;
    }
    
    + (Class)transformedValueClass {
        return [NSData class];
    }
    
    - (id)transformedValue:(id)value {
        //Take an NSArray archive to NSData
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
        return data;
    }
    
    - (id)reverseTransformedValue:(id)value {
        //Take NSData unarchive to NSArray 
        NSArray *array = (NSArray*)[NSKeyedUnarchiver unarchiveObjectWithData:value];
        return array;
    }
    
    @end
    

    上面是NSManagedObject的接口,现在创建一个使用它的接口,例如:

    数组.h

    #import <CoreData/CoreData.h>
    
    @class Arrays;
    
    @interface Array :  NSManagedObject  
    {
    }
    
    @property (nonatomic, retain) id myArray;
    @property (nonatomic, retain) Arrays * arrayOfArrays;
    
    @end
    

    数组.m

    #import "Array.h"
    
    #import "Arrays.h"
    
    @implementation Array 
    
    @dynamic myArray;
    @dynamic arrayOfArrays;
    
    @end
    

    在XCDataModel中,数组需要将myArray属性设置为可选(通常总是选中),类型为:可转换,值转换器名称为:arraytodataTransformer

    现在你可以使用它了;

    NSMutableArray* positionArray;
    positionArray = [[NSMutableArray alloc] arrayWithCapacity:[myArray count]];
    
    for(NSArray *pos in myArray) {
            [positionArray addObject:[NSString stringWithFormat:@"%@",pos]];
    }
    
    NSLog(@"ArrayCtrl : positionArray cnt = %d",[positionArray count]);
    
    
        //Now add the positionArray to CoreData using the setValue & myArray Key
        Array *array = (Array*)[NSEntityDescription insertNewObjectForEntityForName:@"Array" inManagedObjectContext:self.managedObjectContext];
        [array setValue:positionArray forKey:@"myArray"];
        [myArrays setMyArrays:array];
        [self saveAction:array];
        [positionArray release];
    

    要从CoreData中检索数据,请执行以下操作:

    使用一对一关系,因此myarray只指向一个数组元素

    NSArray *positionArray = [myArrays.array valueForKey:@"myArray"];
    

    如果您使用的是一对多,并且事物的名称如上所述,那么您将得到一个nsset。

    核心数据应该将数组存储为数据库中的一个blob,并且可以很快地写入一个大的数组,比如说一个具有3500个对象的数组只需要不到一秒钟的时间。性能与使用几乎相同的概念存储和检索uiimage的方式相当。我认为检索速度更快。 另一种方法是将数组的每个值分别写入核心数据。为此,您需要创建适当的NSManageObject,但请注意,您必须为每个数组值保存3500次,对于3500个项,这将需要20到30秒。 因此,上述方法对于一次将大型阵列写入到核心数据中,并一次性检索到它们是非常有用的。 花了几个小时在这个上面,就要放弃了,然后我看到了光明!

    推荐文章