在Objective-C中,I';我试图封装多个可出错的调用和;return";最有用的错误
我把“return”放在引号里,因为我不想逐字逐句地把它还回去。我希望这样做类似于为在Objective-C中,I';我试图封装多个可出错的调用和;return";最有用的错误,objective-c,cocoa,error-handling,nserror,Objective C,Cocoa,Error Handling,Nserror,我把“return”放在引号里,因为我不想逐字逐句地把它还回去。我希望这样做类似于为[NSString stringWithContentsOfFile:usedEncoding:error:传递指针的方式 我想让parseFiles:error返回nil,并让传入的错误引用包含第一个或第二个错误,具体取决于哪个错误失败。这似乎是一个很好的方法 编辑:对不起,我应该更清楚我的问题出在哪里。如果第一条路径是伪造的,它的功能与我所希望的一样。(我从外部获取错误实例并打印出来。)如果第一条路径是合法的
[NSString stringWithContentsOfFile:usedEncoding:error:
传递指针的方式
我想让parseFiles:error
返回nil,并让传入的错误引用包含第一个或第二个错误,具体取决于哪个错误失败。这似乎是一个很好的方法
编辑:对不起,我应该更清楚我的问题出在哪里。如果第一条路径是伪造的,它的功能与我所希望的一样。(我从外部获取错误实例并打印出来。)如果第一条路径是合法的,正如下面的填充字符串所暗示的,我将获得EXC\u BAD\u ACCESS
但现在我把它修好了。我需要在parseFiles:error:
方法中将其称为*error
,并在检查是否失败时使用==nil
。我想如果(错误),我可以
编辑2好的,它不工作。我获得了EXC\u BAD\u访问权限
。我不确定在检查错误的条件下我做错了什么
@implementation PassingError
- (id)init {
self = [super init];
NSError *error;
[self parseFiles:@"/untitled.py" error:&error];
if (error != nil) {
NSLog(@"I failed because: %@", error);
}
return self;
}
// Wraps with reading errors.
- (NSString *)parseFiles:(NSString *)path error:(NSError **)error {
NSStringEncoding enc1;
NSString *contents1 = [NSString stringWithContentsOfFile:path
usedEncoding:&enc1 error:*&error];
// there was a read error
// I need an asterisk here...
if (*error != nil) {
// ...and also one here
NSLog(@"FIRST ERROR: %@", *error);
return nil;
}
// here is where you'd do something that might cause another error,
// I'll just try and read a second file for simplicity
NSStringEncoding enc2;
NSString *contents2 = [NSString stringWithContentsOfFile:@"/untitled.py"
usedEncoding:&enc2 error:*&error];
// there was a SECOND error
if (*error != nil) {
NSLog(@"SECOND ERROR: %@", *error);
return nil;
}
// return both or whatever
return [NSArray arrayWithObjects:contents1, contents2, nil];
}
@end
在Objective-C中传递指针可能会让人困惑。我记得我很难理解需要做什么。当您有这样一种方法时:
- (BOOL) saveValuesAndReturnError:(NSError **) error
{
BOOL success = [self doSomethingImportant];
if (!success && error)
{
// Unsuccessful and error is a valid ptr-to-ptr-to-NSError.
// Basically, someone has given us the address of a (NSError *).
// We can modify what that pointer points to here.
*error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
}
return success;
}
// If the caller doesn't care that it failed:
[someObject saveValuesAndReturnError:NULL];
// Or, if the caller wants to get error information on failure
NSError *anError = nil;
BOOL success;
// pass address of our (NSError *)
success = [someObject saveValuesAndReturnError:&anError];
if (!success)
{
// anError now points to an NSError object, despite being initialised to nil,
// because we passed the address of our NSError ptr, the method was able to
// change where `anError` points to.
NSLog (@"An error occurred while saving values: %@", anError);
}
这将按如下方式调用:
- (BOOL) saveValuesAndReturnError:(NSError **) error
{
BOOL success = [self doSomethingImportant];
if (!success && error)
{
// Unsuccessful and error is a valid ptr-to-ptr-to-NSError.
// Basically, someone has given us the address of a (NSError *).
// We can modify what that pointer points to here.
*error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
}
return success;
}
// If the caller doesn't care that it failed:
[someObject saveValuesAndReturnError:NULL];
// Or, if the caller wants to get error information on failure
NSError *anError = nil;
BOOL success;
// pass address of our (NSError *)
success = [someObject saveValuesAndReturnError:&anError];
if (!success)
{
// anError now points to an NSError object, despite being initialised to nil,
// because we passed the address of our NSError ptr, the method was able to
// change where `anError` points to.
NSLog (@"An error occurred while saving values: %@", anError);
}
也许在这种情况下,一个非常相关的阅读是一个完全涵盖这个主题的阅读
然而。。。
我记得不久前读到过这样一篇文章:通过方法参数返回错误的方法,例如stringWithContentsOfFile:usedEncoding:error:
不能保证不修改错误参数以获得成功。换句话说,如果方法成功,则不能依赖error参数的值。在您的特定情况下,最好执行以下操作:
- (NSString *)parseFiles:(NSString *)path error:(NSError **)error {
NSStringEncoding enc1, enc2;
NSError *innerError;
NSString *contents1 = [NSString stringWithContentsOfFile:path
usedEncoding:&enc1
error:&innerError];
if (contents1 == nil)
{
if (error) *error = innerError;
return nil;
}
NSString *contents2 = [NSString stringWithContentsOfFile:@"/untitled.py"
usedEncoding:&enc2
error:&innerError];
if (contents2 == nil)
{
if (error) *error = innerError;
return nil;
}
// do whatever with contents1 and contents2
}
如果第一个调用返回一个错误,您将从该方法返回,因此您永远不需要返回两个对象。还有,
*&
的东西是怎么回事?我以为我在那里遇到了EXC\u BAD\u访问错误,这就解决了它,但我走过去发现问题出在其他地方。我编辑了代码来删除那些东西。另外,我不是说我想返回两个对象,我只是想访问相关的错误。这主要是一个指针语法问题。但您的代码已经做到了这一点…它不起作用,我的修复程序也不起作用。当我检查第一个错误时,我不确定我在语法上应该做什么。如果是if(*error)
或if(&error)
或if(*error!=nil)
等,您应该首先确保error
是指向指针的非空指针,否则您可以取消引用null
。感谢您的详细回答和链接!是否应在调用之间将innerError重置为nil?你说你不能确定它在content1调用中没有被修改,你能确定content2调用覆盖了它吗?@zekel:是的,你可以将它设置为nil
,以确保安全,但我认为目前这不是必要的。error
参数是一个输出参数,因此理论上它不应该依赖于给定的任何输入值(我想不出它尝试读取给定指针的任何理由),但谁知道呢!与其后悔,不如谨慎行事。