0

好的,所以我一直在研究数据库类,并被告知要使用异常。但是,我阅读了 Apple 开发人员指南,以尽可能避免异常并改用 NSError。(https://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Chapters/ocExceptionHandling.html

所以它让我思考:我是否使用了正确的方法?在这种情况下我应该使用 NSErrors 吗?

+(long)insertTrack:(Track *)track Database:(Database *)db {
@try {
sqlite3_exec(db.dataBase, "BEGIN", 0, 0, 0); //Start transaction

const char *sqlTrack = "INSERT INTO ...";
if(sqlite3_prepare_v2(db.dataBase, sqlTrack, -1, &addTrackStatement, NULL) != SQLITE_OK) {
     @throw [NSException exeption....]       
}

//Bind variables
sqlite3_bind_text(...);

if(SQLITE_DONE != sqlite3_step(addTrackStatement)) {
    @throw [NSException exeption....]
}
else {
    long insertedTrack = sqlite3_last_insert_rowid(db.dataBase);
    sqlite3_exec(db.dataBase, "COMMIT", 0, 0, 0); //End transaction

    return insertedTrack;
}
}
@catch(NSException *exception) {
    //Log the exception and ROLLBACK!
}
@finally {
    sqlite3_clear_bindings(addTrackStatement);
    sqlite3_reset(addTrackStatement);
    sqlite3_finalize(addTrackStatement); 
}
}

所以我的问题又来了:我是否应该使用返回值来表明准备或执行 sql 语句时出现了问题?我应该像现在一样使用 NSError 还是使用 Exception ?

4

2 回答 2

2

iOS 上的异常实现非常糟糕且效率低下。但是由于错误(可能)很少见,而且 SQL 操作无论如何也不是很快,所以您使用的(就性能而言)可能并不重要,只要您不使用“找不到条目”的异常”和“没有更多数据”的情况。

在有大量操作顺序的情况下,异常可能很方便,因为您不必单独处理错误处理并在每个操作之后进行清理。但是,在上述情况下(在每次操作后您仍然必须测试错误),好处并不是那么大。

在这种情况下可以使用“穷人的例外”方案:

errorCode = NoError;

do {
    rcode = operation1();
    if (rcode) { 
        errorCode = ErrorA;
        break;
    }        
    rcode = operation2();
    if (rcode) { 
        errorCode = ErrorB;
        break;
    }        
    rcode = operation3();
    if (rcode) { 
        errorCode = ErrorC;
        break;
    }
    <More stuff>
} until(FALSE);

if (errorCode == NoError) {
    <do normal path stuff>
}
else {
    <do error path stuff>
}

这在我所知道的所有平台上都相当有效,并且很容易翻译成大多数其他编程语言,即使是那些没有例外的语言。

于 2012-05-15T12:47:32.853 回答
1

我建议在这种情况下使用NSError ,因为如果您知道原因,您可以从错误中恢复,因此您可以发布错误代码并从中恢复。当您不知道如何从它们中恢复并希望它们用于您的 release时,将使用NSExceptions。在此处阅读有关错误与异常的更多信息。您可以在此处获取sqlite 错误代码和消息列表。基于它们,您可以在代码中处理它们。

于 2012-05-15T12:45:06.850 回答