![](/img/trans.png)
[英]Try-catch exception handling practice for iPhone/Objective-C
[英]iPhone development: How to Catch Exception/NSError in Objective-C?
我希望我的应用程序永远不会愚蠢地崩溃。 我知道代码质量是解决此问题的根本原因。 但是我仍然需要一个应用程序,以便在发生意外错误时永不崩溃。 这是我想要尝试的代码。
-(void)testException
{
@try
{
NSString* str;
[str release];
}
@catch(NSException* ex)
{
NSLog(@"Bug captured");
}
}
我知道这个不起作用。 因为release
永远不会引发异常。 这是我的问题:
这是我读过的
我来自一个经验丰富的Microsoft程序员背景,其中catch异常或意外异常总是阻止我的程序在非常糟糕的环境中崩溃。
你们/ gals(Mac天才程序员)是如何制作无崩溃程序的? 分享您的经验。
Objective-C是一个非托管运行时; 您编译的代码直接在CPU上运行,而不是在虚拟机中运行。 这意味着您没有可以像在.NET VM或JVM中运行时那样捕获每种可能的故障模式的监控层。 它的长短是你要完全确定程序不会崩溃的唯一方法是非常仔细地编码并进行非常彻底的测试。 即便如此,你也不确定,你只是认为你是。
最新版本的Xcode集成了Clang静态分析器(“构建”菜单中的“构建和分析”),可以识别某些类别的潜在错误 - 例如,我很确定它会标记上面的示例。 但这里没有灵丹妙药; 唯一的解决方案就是努力工作。
测试测试测试测试
您可以花一整天时间编写异常处理代码以查找可能的异常(实际上永远不会发生),或者您可以创建全面的测试套件,并且只为实际发生的情况编写异常处理程序。
这就是我几乎从不编写异常处理程序的原因。 如果您修复了导致异常的基础问题,那么您不需要处理任何事情。
当然,有些情况下无法确保方法调用不会导致异常并且您需要做好准备,但将所有内容包装在@ try / @ catch块中绝对不是解决方案。
你遇到的一个问题是str永远不会被初始化,这意味着str可能指向nil(但这不能保证)。 它绝对指向垃圾。
如果您单步调试代码,我几乎可以保证您的版本在nil上调用,在Objective-C中完全有效。
试着这样做:
NSString *str = [[NSString alloc] initWithString:@"a string"];
[str release];
[str release];
调用释放不释放对象,它只是将保留计数减1.当对象保留计数为0时,
[self dealloc];
被自动调用。
如果上面的代码没有立即抛出异常,可能是因为实际的释放消息在某个未来的某个时间点被延迟了(我不确定在保留计数达到0之后何时调用dealloc。我认为它会被立即调用在同一个线程上,但其他一些Cocoa忍者肯定会知道)。
你可以做的是为NSObject添加一个类别并实现dealloc和release方法,并尝试在那里捕获你的异常。
- (void)dealloc{
@try
{
[super dealloc];
}
@catch(NSException* ex)
{
NSLog(@"Bug captured");
}
}
- (void)release{
@try
{
[super release];
}
@catch(NSException* ex)
{
NSLog(@"Bug captured");
}
}
额外的好处是,此代码对您应用中的每个对象都有效,因为它是NSObject上的一个类别。
尽管如此,如果你只是练习它们的内存管理规则,你会没事的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.