Ios 当非无效方法到达Objective-C中的末尾时会发生什么?

Ios 当非无效方法到达Objective-C中的末尾时会发生什么?,ios,objective-c,return,Ios,Objective C,Return,问题我想问一下,当一个非void方法到达末尾而没有返回时会发生什么 环境这个问题与iOS和Objective-C有关。我不确定这个问题中描述的事情在其他地方的表现 介绍和背景 通常,当您在Objective-C中声明非void方法且未指定返回值时,Xcode显示编译错误 控件到达非无效函数的末尾 并禁止您编译,除非您解决了此问题 系统可以非常智能地检测您的代码是否能够达到非无效函数的末尾-识别您的if/else块是否满足所有选项,通过开关等 然而,我发现了一个(可能还有其他的)brain-f*

问题我想问一下,当一个非void方法到达末尾而没有返回时会发生什么

环境这个问题与
iOS
Objective-C
有关。我不确定这个问题中描述的事情在其他地方的表现


介绍和背景

通常,当您在Objective-C中声明非void方法且未指定
返回值时,Xcode显示编译错误

控件到达非无效函数的末尾

并禁止您编译,除非您解决了此问题

系统可以非常智能地检测您的代码是否能够达到非无效函数的末尾-识别您的if/else块是否满足所有选项,通过开关等

然而,我发现了一个(可能还有其他的)brain-f**选项,让编译器思考“嘿,伙计,是的,这段代码看起来非常好,让我们编译它并享受乐趣吧!”。这是偶然的,引起了一些头痛。这是密码

代码

typedef enum eSections { eSectionRecent, eSectionAround, eSectionAll } eSections;

...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger localSection = section;
    if (numberOfSections == 2) localSection++;

    switch ((eSections)@(localSection))
    {
        case eSectionRecent:
            return 1;
            break;
        case eSectionAround:
            return 1;
            break;
        case eSectionAll:
            return 3;
            break;
    }
}
结果

有了这段代码,编译器认为可以让这个方法编译,因为有一个switch对象是一个枚举,每个可能的枚举值都有一个实例,所以,是的,这听起来是合法的

所以我真的很感兴趣,现在编译器被搞糊涂了,让我把这个错误的代码运行到底会发生什么

错误

对任何感兴趣的人来说,我的错误出现在
(eSections)@(localSection)
,我没有在eSections中键入
localSection
,而是键入了
@(localSection)
,它编译成一个
NSNumber
,并使用指向对象的指针代替值,从而无法与任何
大小写匹配,因为指针可以很长(很可能不是0、1或2)。接下来发生的事情是,该项目试图为大量单元分配空间(我认为不指定返回值就像让我们在那里抛出一些内存值),最终由于内存压力而导致应用程序崩溃


谢谢你的回答

结果是未定义的行为


通常,调用者会得到未指定的垃圾作为返回值。无论寄存器中剩下什么,或者在某些情况下,调用者为局部变量使用的堆栈位置就是调用者得到的。

你也可以问:当我访问未初始化的指针时会发生什么。你会得到垃圾的和平,因为编译器不能再保护你了。我无法想象为什么有人会否决这个问题。这实际上是我最近在这里看到的一个更好的问题。这很清楚,它显示了良好的努力,并且它有一个明确的例子来说明这个问题。没有否决票的基础。学习汇编语言。否决票的选民有任何改进的要求吗?谢谢你的回答!我想知道,我能够编译所提到的代码并(可能)将其发布到AppStore是不是一个SDK错误?这就是为什么我认为存在“控件到达非void函数末尾”的正常情况编译器错误,而不是警告。另外,对于“…或者,在某些情况下,某些堆栈位置…”语句,您是否有任何证据/更多解释?我真的非常有兴趣在这里更深入!这不是工具中的错误。C和Objective-C允许你,程序员,向自己的脚开枪。类型转换表达式是指告诉编译器某个表达式属于某种类型,即使它看起来不是这样。所以,它编译起来就好像是这样。只要理论上可能函数到达非void函数的末尾,编译器就可以报告错误,但这将迫使我们添加默认情况或在我们知道实际不可能的情况下添加无关的
return
语句。这是一种权衡。