什么是使iOS应用程序崩溃的可靠方法?

Nes*_*tor 134 iphone objective-c ios

我想在用户执行一个真实用户不太可能意外执行的特定操作时故意让它崩溃,从而测试我的应用程序崩溃报告.

但是什么是使编译时不会产生警告的应用程序崩溃的可靠方法?

编辑:请注意,这个问题的许多看似明显的答案导致Cocoa捕获的异常,因此不会导致应用程序崩溃.

Dai*_*jan 138

在Objective-C中直接使用C导致访问不良

strcpy(0, "bla");
Run Code Online (Sandbox Code Playgroud)

注意:虽然这适用于我所知道的任何系统 - 在未来版本的C运行时或编译器中,这可能不会导致崩溃.请参阅Objective-C中的空指针取消引用未定义行为?)

(在swift中你必须桥接到objC才能这样做)

  • 显然(http://stackoverflow.com/questions/13651642/is-null-pointer-dereference-defined-behavior-in-objective-c),这是未定义的行为,实际上是一个非常糟糕的答案!编译器可以合法地优化两个语句而不做任何事情.我建议你删除这个答案.它可能会引导人们真正做到这一点. (4认同)
  • 在ios和osx以及windows和redhat它总是崩溃所以在给定的上下文中,我会说它有效.我将添加免责声明 (3认同)

djr*_*ero 96

我目前最喜欢的:

assert(! "crashing on purpose to test <insert your reason here>");
Run Code Online (Sandbox Code Playgroud)

经典之作:

kill( getpid(), SIGABRT );
Run Code Online (Sandbox Code Playgroud)

还有一些pr0n:

*(long*)0 = 0xB16B00B5;
Run Code Online (Sandbox Code Playgroud)

所有这些都会导致崩溃报告工具捕获崩溃.

  • 恕我直言`断言'不是调试功能.失败的断言是你认为不可能的错误.最好是中止,甚至是发布版本,而不是继续运行具有不可预测后果的程序. (18认同)
  • assert不会在发布版本上崩溃,这就是为什么它是一个断言 (14认同)
  • 这取决于你的构建设置; 另外,我认为问题在于测试,在测试版本中保留断言似乎没问题 (6认同)
  • @Sulthan:`assert()`是一个调试功能,在发布版本中留下这样的瑕疵是没有意义的.有单元测试. (5认同)
  • 许多人(包括我)在发布版本中留下断言.没有理由禁用它们. (3认同)

Die*_*Epp 26

由于我们都使用Clang for iOS,这是相当可靠的:

__builtin_trap();
Run Code Online (Sandbox Code Playgroud)

这样做的好处是它专门用于此目的,因此不应生成任何编译器警告或错误.


kmk*_*lan 24

abort(); 导致异常终止......那是一次崩溃.


Tau*_*aum 22

一个好的旧堆栈怎么样溢出:)

- (void)stackOverflow
{
    [self stackOverflow];
}
Run Code Online (Sandbox Code Playgroud)


wir*_*arr 16

最受欢迎的一个 - 无法识别的选择器崩溃:

NSObject *object = [[NSObject alloc] init];
[object performSelector:@selector(asfd)];
Run Code Online (Sandbox Code Playgroud)

确保你没有在该类中实现-asdf方法哈哈

或索引超出绑定异常:

NSArray * array = [NSArray array];
[array objectAtIndex:5];
Run Code Online (Sandbox Code Playgroud)

而且当然 kill( getpid(), SIGABRT );


bor*_*ero 10

我认为在Swift中你很容易抛出一个致命的错误:

func foo() {
    fatalError("crash!")
}
Run Code Online (Sandbox Code Playgroud)

它实际上甚至打算使用此功能,以防出现问题,以使应用程序崩溃.

为了避免特殊情况下的if语句,您也可以使用precondition.它类似于 assert,因此意图(如果需要)非常清楚,并且在最终版本中没有删除assert.它用得像precondition(myBoolean, "This is a helpful error message for debugging.").


And*_*kha 9

向已释放的对象发送消息

  • 这实际上非常不可靠.只要不重用它们的内存,您仍然可以向已释放的对象发送消息.这就是人们历史上很难调试双版本错误的全部原因.只有当另一个对象回收内存时,发送消息才会导致异常. (34认同)

Ste*_*ers 7

exit(0);
Run Code Online (Sandbox Code Playgroud)

(必须......输入... 30个字符)


Ale*_*olo 6

您还可以引发异常:

[NSException raise:NSInternalInconsistencyException
            format:@"I want to test app crashes!."];
Run Code Online (Sandbox Code Playgroud)

  • 我不认为异常是好方法,捕获异常很常见,所以你可能会意外地捕获它.捕获信号并不常见,因此访问不良或类似的事情会更可靠.:) (2认同)