1

I am developing an iPad application where I would have to perform a lot of read/write operations on a database(i have to store the clicks on the view in a database nad based on the clicks make perform some operations). I am confused as to how to proceed in this case. Should I just create a SQLIte database and perform the read/writes(will this slow down the response time of the app??) or is there some other technique(i have heard of Core data but not sure if this work for my case). Please help me

Thanks

Ajith

4

3 回答 3

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;
}

现在,这些将进入数据库,但如果您的文档想要查看它们,则必须执行提取。根据您的用例选择最好的。不过,我想你会很好地处理第一个例子。

于 2012-04-17T00:30:15.910 回答
0

您最好的选择是将您的操作流式传输到文件系统上的文件中。然后你可以把它留在那里,或者如果你真的需要,通过 Core Data 将它上传到 SQLite。这样做的原因是,如果你ManagedObjectContext为每一个偶数都提交你的,事情会运行得很慢。

使用:backingFile = [NSFileHandle fileHandleForUpdatingAtPath:eventsFilePath];将您的事件附加到使用[backingFile writeData:...];

请记住,关系数据库的主要目的是“搜索”数据。如果您不打算搜索 UI 点击事件(我怀疑您会这样做),那么流式传输到文件是您最好的选择。

于 2012-04-16T18:27:56.047 回答
0

如果有很多点击,您肯定不想将它们中的每一个单独写入数据库。也许,累积鼠标动作并将它们保存在-mouseUp:事件中是一个很好的折衷方案。

通过简化程序,Core Data 可能会有所帮助。它使您可以非常快速地创建对象并推迟将它们保存到持久存储中。但是,如果你安装一个,你可以用 SQLite 达到同样的效果CFRunLoopObserver,等到没有事件,然后将一批数据写入数据库。

无论您选择什么,策略都是累积点击并批量保存。

于 2012-04-16T16:26:16.513 回答