136

我想通过在用户执行真实用户不太可能意外执行的特定操作时故意让它崩溃来测试我的应用程序的崩溃报告。

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

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

4

18 回答 18

141

在 Objective-C 中直接使用 C 导致错误访问

strcpy(0, "bla");

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

(在swift中,您必须桥接到objC才能做到这一点)

于 2012-11-22T10:36:46.613 回答
98

我目前最喜欢的:

assert(! "crashing on purpose to test <insert your reason here>");

经典:

kill( getpid(), SIGABRT );

还有一些pr0n:

*(long*)0 = 0xB16B00B5;

所有这些都会生成由我的崩溃报告工具捕获的崩溃。

于 2012-11-22T10:38:59.877 回答
27

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

__builtin_trap();

这样做的好处是它正是为此目的而设计的,因此它不应该生成任何编译器警告或错误。

于 2012-11-23T04:14:19.537 回答
25

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

- (void)stackOverflow
{
    [self stackOverflow];
}
于 2014-01-28T19:07:52.340 回答
24

abort();导致异常终止……那是崩溃。

于 2012-11-22T15:11:26.390 回答
16

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

NSObject *object = [[NSObject alloc] init];
[object performSelector:@selector(asfd)];

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

或索引超出范围异常:

NSArray * array = [NSArray array];
[array objectAtIndex:5];

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

于 2012-11-22T10:37:37.580 回答
13

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

func foo() {
    fatalError("crash!")
}

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

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

于 2015-03-01T11:57:53.043 回答
9

向已释放的对象发送消息

于 2012-11-22T10:27:28.990 回答
7
exit(0);

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

于 2012-11-28T00:08:02.273 回答
6

您还可以引发异常:

[NSException raise:NSInternalInconsistencyException
            format:@"I want to test app crashes!."];
于 2012-11-22T10:34:33.617 回答
3

将手势识别器添加到可识别 10 根手指点击的视图(iPhone 为 5 根手指,因为 10 可能会有点拥挤)。GR 有一个附加的方法,可以执行前面提到的任何一种可靠的方法来让你的应用程序崩溃。大多数用户不会将 10 根手指放在您的应用程序上,因此您可以避免普通用户意外导致崩溃。

但是,您应该能够使用诸如 Testflight 之类的东西,或者只是将其部署到个人设备上并在将其提交给 Apple 之前在野外进行测试。强制崩溃可能会让您的应用程序被 Apple 拒绝。

于 2012-11-27T19:43:27.303 回答
2

可以尝试类似的东西

NSArray* crashingArray = [NSArray arrayWithCapacity:1];
[crashingArray release];

应该在 EXC_BAD_ACCESS 上崩溃(可能需要再次释放它,但通常它应该已经像这样崩溃了)

于 2012-11-22T11:45:23.973 回答
1

我会去:int raise(int sig);

获取更多信息>man raise

于 2012-11-22T12:37:49.640 回答
0

我只会正常终止该过程:

kill(getpid(), SIGKILL);

因此,如果您安装带有信号的处理程序,您还可以处理崩溃,完成写入打开的文件和这些事情。

于 2012-12-14T02:07:16.090 回答
0

我用

[self doesNotRecognizeSelector:_cmd]; 
于 2014-06-04T13:42:37.670 回答
0

使用 RubyMotion 时,我使用这个:

    n=Pointer.new ('c', 1)
    n[1000] ='h'
于 2015-03-05T16:29:24.633 回答
0

试试这个:

- (IBAction)Button:(id)sender
{
    NSArray *array = [NSArray new];
    NSLog(@"%@",[array objectAtIndex:8]);
}
于 2015-03-18T11:13:37.747 回答
-1

一个错误的NSLog陈述会做到这一点

NSLog(@"%@",1);
于 2012-12-23T10:40:48.257 回答