ios - Xcode Memory Graph 报告释放对象的泄漏
问题描述
Xcode 调试内存图工具已检测到释放可可对象的泄漏,如下面的代码所示。基本上,只要在分配可可对象的块中捕获异常,就会发生这种情况。您可以尝试使用任何 sdk,这里是 macOS 11.1,尽管 iOS 14.4 sdk 会产生相同的结果。您可以在对象范围结束后添加断点并启动 Debug Memory Graph 以查看泄漏的 NSString 对象。你怎么看,实际上是一个错误或错过了什么?
@interface TestClass : NSObject
- (void)testMethod;
@end
@implementation TestClass
- (void)testMethod {
@try {
NSMutableString *string = [NSMutableString new];
NSLog(@"%p: %@", string, string);
@throw [NSException exceptionWithName:@"exception1" reason:@"exception1" userInfo:nil];
} @catch(NSException *exception) {
NSLog(@"%@", exception);
}
}
- (void)dealloc {
NSLog(@"dealloc method called!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
{
TestClass *testClass = [[TestClass alloc] init];
[testClass testMethod];
}
NSLog(@"byebye");
}
return 0;
}
控制台输出:
0x1006a6330: whatever
exception1
dealloc method called!
byebye
问题导航器窗格中的泄漏对象摘要
LeakTest - 11521 Group
Memory Issues - (2 leaked types) Group
runtime: Memory Issues - (2 leaked types): 1 instance of __NSCFString leaked
0x1006a6330
runtime: Memory Issues - (2 leaked types): 1 instance of CFString (Storage) leaked
0x1006a63a0
快速查看上下文菜单项中泄露的 CFString 对象的内容
po [(NSString *)0x1006a6330 debugDescription]
whatever
解决方案
这是预期的行为。在大多数情况下,ARC 不是异常安全的。可以通过传递来开启 ARC 的异常处理-fobjc-arc-exceptions
(在 Objective-C++ 中默认开启),但它的成本很高。Objective-C 异常不打算用作通用错误处理机制(例如 Swiftthrows
或 C++ 异常)。如ARC 文档的例外部分所述:
标准的 Cocoa 约定是异常表示程序员错误并且不打算从中恢复。默认情况下使代码异常安全将对通常实际上不关心异常安全的代码施加严重的运行时和代码大小惩罚。因此,ARC 生成的代码默认会在异常情况下泄漏,如果进程无论如何都将立即终止,这很好。关心从异常中恢复的程序应该启用该选项。
有关 Objective-C 中标准错误处理模式的信息,请参阅处理Objective-C 编程中的错误。
推荐阅读
- javascript - 如何更改此方法的控制通量变量
- python - Python - 日期标记文本文件的每一行
- angular - mat-tree 遇到 css 网格
- blueprism - selectContextMenuItem 方法返回“该方法的参数无效”
- ruby - 一段时间后,使用 slack-ruby-bot gem 从 slack bot 获得多个答案
- reactjs - appendchild 一个 React 组件消息
- php - 删除表单元素的表单更新时实体关系设置为空
- javascript - 使用 jQuery 插件使用鼠标滚轮水平滚动
- angular - Visual Studio 2019 中的 Angular Intellisense
- ssh - 从 SSH 终端转发端口