objective-c - 使用 CFRelease 释放的对象会导致明显的崩溃,但这种情况很少见

标签 objective-c ios crash

我有以下方法:

+ (NSString*) getMD5HashFromFile:(NSString*)filePath {
    CFStringRef md5hash = FileMD5HashCreateWithPath((CFStringRef)filePath, FileHashDefaultChunkSizeForReadingData);
    NSString *hashStr = (NSString*)md5hash;
    CFRelease(md5hash);
    return hashStr;
}

我在模拟器上遇到了随机崩溃,大约 20-30 次执行中有 1 次崩溃。这不一致的事实并没有帮助我之前进行更深入的挖掘。

现在我再次看到代码,很明显 md5hash 在返回之前被释放,这意味着返回的对象已失效。返回值以一致的方式在另一个方法中使用,有时会崩溃,但并非总是如此。我的问题是为什么这种情况很少发生而不总是发生。

它是否与 Obj-C 和 C 代码的混合以及自动释放池的工作方式有关?

注意:这个错误似乎是通过使用 NSString *hashStr = [NSString stringWithString:(NSString*)md5hash] 修复的,这对我来说很有意义。

最佳答案

仅仅因为一 block 内存被释放和释放并不意味着它会立即返回给操作系统。您的应用程序可以根据多种因素和多个层将其保留任意时间。操作系统有时有更重要的事情要做,而不是回收你释放的每一 block 内存,并可能在半秒后再次请求。访问您已调用 free() 但技术上拥有的内存不会生成信号。这就是 MallocScribble 存在的原因。它会用垃圾 (0x55) 覆盖您释放的内存,以便在您使用释放的内存时更加明显。

尝试以下操作:

char *foo = malloc(100);
strcpy(foo, "stuff");
free(foo);
printf("%s", foo);

尽管完全错误,但大多数情况下它会正常工作。现在,编辑您的 Scheme>Diagnostics 并启用 Scribble。重新运行,你会看到一堆“U”(0x55)表明你在读废话。但它仍然不会崩溃。

您可能对 Matt Gallagher 的 A look at how malloc works on the Mac 感兴趣有关该主题的更多信息。

关于objective-c - 使用 CFRelease 释放的对象会导致明显的崩溃,但这种情况很少见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9571585/

相关文章:

html - 移动设备上的文本输入对齐错误(可能仅限 iOS,尚未尝试 Android)

iphone - 删除单元格和重新加载 TableView 时访问权限不佳

ios - 动态 View 的自动布局约束

objective-c - 以两种方式显示 View (推送和模态)

ios - 如何在一个 NSFetchRequest 中获取核心数据关系?

ios - 由于 iOS 13.3.1 崩溃,Apple 拒绝了该应用程序

ios - iOS异常代码列表

Jquery 1.6.2 使 IE8 选项卡崩溃

ios - 自定义多个标签或按钮

iphone - 根据用户输入绕过我的部分代码,obj-C if else if or #if#elif?