我正在开发一个iPad应用程序,我必须在数据库上执行大量的读/写操作(我必须根据点击执行某些操作将数据库中的点击存储在数据库中)。在这种情况下,我很困惑如何处理。我应该只创建一个SQLIte数据库并执行读/写(这会减慢应用程序的响应时间吗?)还是有一些其他技术(我听说过Core数据但不确定这是否适用于我的情况) 。 请帮帮我
由于
阿吉特
答案 0 :(得分:1)
如果您只是按顺序保存它们,然后以相同的顺序读回它们,那么常规文件可能是最好的。但是,如果您要执行其他任何操作,请使用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;
}
现在,这些将转到数据库,但如果您的文档想要查看它们,则必须执行提取。根据您的用例选择最佳选择。我想你会在第一个例子中做得很好。
答案 1 :(得分:0)
如果有大量点击,您绝对不希望将它们分别写入数据库。也许,积累鼠标操作并将其保存在-mouseUp:
事件上是一个很好的折衷方案。
核心数据可以通过简化程序来帮助我们。它允许您非常快速地创建对象,并将它们保存到持久性存储中。但是,如果安装CFRunLoopObserver
,则可以使用SQLite获得相同的效果,等待没有事件并将一批数据写入数据库。
无论您选择什么,策略都是累积点击次数并分批保存。
答案 2 :(得分:0)
最好的办法是将您的操作流式传输到文件系统上的文件中。然后您可以将其保留在那里,或者如果您确实需要,可以通过Core Data将其上传到SQLite。这样做的原因是,如果你为每一个偶数提交ManagedObjectContext
,事情就会非常缓慢。
使用:backingFile = [NSFileHandle fileHandleForUpdatingAtPath:eventsFilePath];
将您的活动附加到[backingFile writeData:...];
请记住,关系数据库的主要目的是“搜索”数据。如果您不打算搜索您的UI点击事件(我怀疑您会这样做),那么流式传输到文件是您最好的选择。