【问题标题】:NSException raise:format: as the last statement in a methodNSException raise:format: 作为方法中的最后一条语句
【发布时间】:2012-05-11 04:06:21
【问题描述】:

我有这个方法:

+ (MHTwitterParser*)createParser:(NSString*)format {
    if ([format compare:@"json"] == NSOrderedSame) {
        return [[MHJsonTwitterParser alloc] init];
    }

    [NSException raise:@"Unknown format" format:@"Unknown format of parser"];
}

编译器抱怨:

Control may reach end of non-void function

这只是一个警告,但没关系。

对此的明显解决方法是在[NSException raise: ... 之后添加例如return nil;

但是,我认为它是不需要的(甚至会误导读者),因为抛出了异常,所以“控制可能到达非空函数的结尾”是不正确的。还是我错过了什么……?仅仅是编译器的缺陷还是有一些相当大的原因?

编译器是Apple LLVM compiler 3.1

【问题讨论】:

  • 这只是一个对象上的方法,如果我愿意,我可以调整该方法以不引发异常,然后我的程序将到达非 void 函数的末尾......我确定在那里还有其他更有用的理由
  • @Paul.s 谢谢保罗。这是有道理的,这是有效的观点。我很好奇是否有人会提出其他解释。

标签: objective-c exception nsexception


【解决方案1】:

原因很简单。

对于编译器,方法[NSException raise: ...] 是一个黑盒方法。它不知道该方法实际上会引发异常。

如果将其与 Java 或 C++ 进行比较,它们的 throw 语句是一种语言特性,编译器确切地知道找到它时会发生什么。在 Obj-C 中它是不同的,有时它取决于运行时条件。请考虑以下事项。

NSException* exception = nil;

if (someCondition) {

   exception = [NSException exceptionWithName:...];
}

[exception raise];

编译器不知道是否真的引发了异常。

【讨论】:

  • 这个解释真的很好,但这不是准确的答案。警告不是因为编译器无法识别NSException,而是它可以在最后一行看到一个非返回语句,就在一个条件之后(可能执行也可能不执行)
  • @geekay 这不是真的。如果您用编译器无法理解的内容替换最后一条语句,例如abort()assert(false),您不会收到警告。这里的问题是编译器不知道引发NSException 会中断程序流程。
  • @sulthan,谢谢伙计,我现在需要深入研究一下。但即使没有NSException 场景,我也面临过这个警告
【解决方案2】:

[exception raise]; 替换为@throw exception; 在功能上是相同的,并且会阻止警告(请参阅:Throwing Exceptions)。

【讨论】:

    【解决方案3】:

    警告之所以存在,是因为并非代码中的每条路径都以编译器认为可能存在问题的 return 语句结尾。也就是说,您可能不应该在这里抛出异常,而应该生成NSError 并返回nil。 Objective-c 中异常和错误的区别在herehere 解释。

    【讨论】:

    • 对,它与NSException 无关,即使有任何其他(不返回)语句作为最后一条语句,也会出现此警告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2013-07-25
    • 2022-01-03
    相关资源
    最近更新 更多