如果您只是要按顺序保存它们,然后以相同的顺序读回它们,那么常规文件可能是最好的。但是,如果您要执行其他任何操作,请使用 CoreData。它不仅仅是一个关系数据库。它允许持久对象图。此外,如果您使用 UIManagedDocument 或您自己的父/子 NSManagedObjectContext 安排,您甚至不会看到数据库命中,因为这一切都发生在后台线程中。
来吧,测试一下。覆盖开始/移动/结束触摸,并在每次触摸时将对象放入数据库。如果您按照我的描述进行操作,您甚至不会注意到数据库命中。
假设模型中有两个实体,MyTouchEvent 和 MyTouch,其中 MyTouchEvent 与 MyTouch 是一对多的关系。
// Call this from touchesBegan, touchesMoved, and touchesEnded...
- (void) saveTouches:(NSSet*)touches kind:(NSString*)kind
{
NSManagedObjectContext *moc = self.document.managedObjectContext;
MyTouchEvent *myTouchEvent = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouchEvent" inManagedObjectContext:moc];
myTouchEvent.kind = kind;
for (UITouch *touch in touches) {
CGPoint touchPoint = [touch locationInView:self];
MyTouch *myTouch = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouch" inManagedObjectContext:moc];
myTouch.x = [NSNumber numberWithFloat:touchPoint.x];
myTouch.y = [NSNumber numberWithFloat:touchPoint.y];
[myTouchEvent addTouchesObject:myTouch];
}
[self.document updateChangeCount:UIDocumentChangeDone];
}
如果您的对象创建成本很高,您可以添加一个方法来创建私有上下文,并在其中完成所有工作,有两种选择。您可以将其作为文档的主要上下文的父级,在这种情况下,您所要做的就是将代码嵌入一个块中,然后在 MOC 上调用 save ...
- (NSManagedObjectContext*)moc
{
if (!_moc) {
_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_moc.parentContext = self.document.managedObjectContext;
}
return _moc;
}
- (void) saveTouches:(NSSet*)touches kind:(NSString*)kind
{
NSManagedObjectContext *moc = self.moc;
[self.moc preformBlock:^{
MyTouchEvent *myTouchEvent = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouchEvent" inManagedObjectContext:moc];
myTouchEvent.kind = kind;
for (UITouch *touch in touches) {
CGPoint touchPoint = [touch locationInView:self];
MyTouch *myTouch = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouch" inManagedObjectContext:moc];
myTouch.x = [NSNumber numberWithFloat:touchPoint.x];
myTouch.y = [NSNumber numberWithFloat:touchPoint.y];
[myTouchEvent addTouchesObject:myTouch];
}
NSError *error = nil;
[moc save:&error];
}];
}
或者,您可以将其设为兄弟,在这种情况下,所有数据库都不会在主线程上运行( UIManagedDocument 的主上下文在主线程上运行,因此在上述情况下,主线程将传递对象到执行保存的上下文)。但是,在这种情况下,您的 document.managedObjectContext 必须执行 FETCH 才能获取放入数据库的任何内容。但是,它在存储期间不会对主线程造成任何性能影响。
- (NSManagedObjectContext*)moc
{
if (!_moc) {
_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_moc.parentContext = self.document.parentContext;
}
return _moc;
}
现在,这些将进入数据库,但如果您的文档想要查看它们,则必须执行提取。根据您的用例选择最好的。不过,我想你会很好地处理第一个例子。