<简短回答> 仅在64位OS X和iOS中。它们并不完全免费。更准确地说,该模型被优化以在正常执行期间最小化成本(将后果转移至其他地方)。 <详细回答> 在32位的OS X和iOS上,即使未抛出异常,异常也会有运行时成本。这些架构不使用零成本异常。在64位的OS X中,ObjC转而借用了C ++的“零成本异常”。除非抛出,否则零成本异常的执行开销非常低。零成本异常有效地将执行成本移动到二进制大小。这是它们最初未在iOS中使用的主要原因之一。启用C++异常和RTTI可以将二进制大小增加50%以上-当然,我预计在纯ObjC中,这些数字会远低于此,因为解缠时执行的内容较少。在arm64中,异常模型从Set Jump Long Jump更改为Itanium派生的零成本异常(根据汇编判断)。然而,惯用的ObjC程序并不是为了从异常中恢复而编写或准备的,因此您应该将它们保留用于您不打算从中恢复的情况(如果您决定使用它们)。更多细节请参见Clang manual on ARC和引用页面的其他部分。
根据Mac OS X v10.5中Objective-C运行时的一些2007年发布说明,他们已经重新编写了Objective-C异常的64位实现,以提供“零成本”的try块和与C ++的互操作性。显然,这些“零成本”try块在进入try时不会产生时间惩罚,而其32位对应项必须调用setjmp()和其他函数。显然,抛出它们是“更加昂贵”的。这是我在苹果发布说明中唯一能找到的信息,因此我必须假设这仍然适用于今天的运行时,因此,32位异常=昂贵,64位异常=“零成本”。