【问题标题】:NSError * returned with bad address - why?NSError * 返回错误地址 - 为什么?
【发布时间】:2013-04-26 20:20:31
【问题描述】:

在下面的代码中,NSError 在返回时显示在 XCode 中,其类类型为“HomeViewController”——我的视图控制器之一。如果我用双指针做了一些不寻常的事情,这将是有道理的,但我没有。为什么会这样?我的代码中是否有一些愚蠢的错误,Core Data 中的错误,还是????

希望我没有自欺欺人!

self->ctx = [(AppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
NSFetchRequest * request = [[NSFetchRequest alloc] init];

NSEntityDescription *entityDescription = [NSEntityDescription
                                          entityForName:@"Street" inManagedObjectContext:self->ctx];

NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc]
                                    initWithKey:@"street" ascending:YES];
NSArray* sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];


[request setEntity:entityDescription];
[request setSortDescriptors:sortDescriptors];

NSError * error;
NSArray *array = [self->ctx executeFetchRequest:request error:&error];
if(error!=nil){
    NSLog(@"%@", @"Critical model error search");
}
_streets = array;

【问题讨论】:

  • 不要使用self->访问ivars。
  • @bbum 感谢您的最佳实践.. 为什么会这样?
  • 这是一个约定。没有真正的危害(除了考虑访问器上是否存在可能很关键的行为),但您不会看到它在深奥的情况之外完成(例如 -copy 方法的实现)。

标签: objective-c xcode


【解决方案1】:

显然,如果没有错误,您使用的方法 ([self->ctx executeFetchRequest:request error:&error]) 不会将其参数设置为 nil,如果发生错误,只会设置为错误。 将你的变量初始化为nil:NSError *error = nil;

正如 cmets 中所指出的,您必须检查调用的返回值,并且只有当它是 nilNO(取决于声明的返回类型)时,NSError 指针才保证有效(包括.nil),即使它是有效的。所以不要使用if(error != nil),而是使用if(!array)if(array == nil)

【讨论】:

  • 这确实是正确的,一般Cocoa要求你在使用NSError之前检查直接返回值,而不是错误是否为nil。如果方法指示失败,错误是 guaranteed 是有效的,但反过来——即使你事先将它设置为 nil,也不能保证成功。
  • 本地变量指向垃圾。您必须设置为 nil(或 NULL)。分析器也会指出这一点:-)
  • ... 除非您使用 ARC 编译 - 然后指向对象的指针被初始化为 nil。
  • 请注意,在调用之前没有理由将局部变量设置为nil,并且不正确地测试error 值是不正确的首先测试返回值。此答案的最后一行不正确。
  • (很好的澄清,顺便说一句。谢谢。)不是真的;返回值必须准确地指示成功/失败,因为您可以将NULL 传递给错误,这样被调用的方法就知道不会浪费任何时间来计算(可能很昂贵)错误信息。因此,要求您始终检查返回值可确保一致性,但不能保证指针将保持不变,从而最大限度地提高了内部实现的灵活性、性能以及——再次——一致性。这是经过深思熟虑的设计决定。
【解决方案2】:

这不断出现。所以,一些具体的例子。

没有理由将 NSError 初始化为 nil。一个警告是,如果你用 &err 调用的对象是 nil,你会得到一个错误的失败,并且检查一个未初始化的错误将会爆炸。 然而,这种失败模式与导致失败的尝试完全不同,实际上,您应该避免接收 nil 的情况(想象一下,如果您的托管对象上下文意外地为 nil——您可能有很多比错误错误更大的问题)。

这是一个完全有效的方法实现,它返回 BOOL 并接受 NSError**。有效,但显然是人为的。但是,这种事情确实发生在多层 API 中。

 - (BOOL)doThis:(NSError**)chaffin
 {
    if (chaffin) *chaffin = 0x42;
    return YES;
 }

计算误差可能很昂贵。如果您只需要知道成功/失败,而不需要知道为什么,则为错误参数传递 null。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-27
    • 2015-08-26
    • 2021-08-29
    • 2019-10-26
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多