Я получил это на работу. Вот как.
Сначала создайте NSValueTransformer примерно так:
ArrayToDataTransformer.h
@interface ArrayToDataTransformer : NSValueTransformer {
}
@end
ArrayToDataTransformer.m
import "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, теперь создайте тот, который его использует, например:
Array.h
#import <CoreData/CoreData.h>
@class Arrays;
@interface Array : NSManagedObject
{
}
@property (nonatomic, retain) id myArray;
@property (nonatomic, retain) Arrays * arrayOfArrays;
@end
Array.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:
используя отношение один к одному, таким образом, myArrays указывает только на один элемент массива
NSArray *positionArray = [myArrays.array valueForKey:@"myArray"];
Если вы используете один-ко-многим, а вещи названы, как указано выше, вы получите NSSet.
Базовые данные должны хранить массив в виде большого двоичного объекта в базе данных, и большой массив можно записать очень быстро, например, для одного из 3500 объектов требуется меньше секунды. Производительность сопоставима с тем, как UIImage хранится и извлекается, используя почти те же концепции. Поиск, я думаю, еще быстрее.
Альтернатива - записать каждое значение массива индивидуально в базовые данные. Для этого вам нужно создать соответствующий NSManageObject, но учтите, что вам придется экономить 3500 раз для каждого значения массива, а для 3500 элементов это займет от 20 до 30 секунд.
Таким образом, описанный выше метод отлично подходит для записи больших массивов в CoreData за один снимок и извлечения их также за один снимок.
Потратил на это несколько часов, собирался сдаться, а потом я увидел свет!