解除分配NSString导致崩溃

时间:2019-03-15 11:41:26

标签: objective-c qt nsstring dealloc

我正在研究Objective-C应用程序。那里有这个片段:

QString result;
NSString *tmp = nil;
tmp = [activeApp bundleIdentifier];
result = QString::fromNSString(tmp);
NSLog(@"activeApplicationBundleId 2");
if (tmp) {
    NSLog(@"dealloc");
   //[tmp dealloc];  // <--- this causes crash
}
else {
    NSLog(@"do not dealloc");
}
return result;

我不明白为什么会崩溃。我已经检查了Apple的文档,并且bundleIdentifier是通过copy定义的属性

@property(readonly, copy) NSString *bundleIdentifier;

我还读到我应该负责释放字符串。为什么会崩溃? 如果我改用:

NSRunningApplication* activeApp = [[NSWorkspace sharedWorkspace] frontmostApplication];
return QString::fromNSString([activeApp bundleIdentifier]);

我会因为不取消分配NSString而导致内存泄漏吗?

以防万一QString :: fromNSString

QString QString::fromNSString(const NSString *string)
Constructs a new QString containing a copy of the string NSString.

预先感谢

1 个答案:

答案 0 :(得分:1)

首先,所有这些都无关紧要,如果您使用ARC,则不应该存在。因此,假设您没有使用ARC,而是进行手动内存管理:

  • 按照惯例,您不拥有bundleIdentifier返回的NSString,因此您不应尝试释放它*

  • 即使您拥有该字符串,也应该通过调用release而不是dealloc来释放它。 release将减少保留计数器,并且仅在保留计数器变为零时才调用dealloc。根据经验,您从不直接调用dealloc;这样做可能会释放仍然从其他地方引用的对象,从而导致内存损坏和严重崩溃

*)属性定义的copy属性具有误导性;它描述了将新值分配给属性时会发生什么。由于该属性已公开声明为readonly,因此将显示实现细节,该细节不应出现在标头的公共定义中(最好是在不公开可见的私有接口扩展中)。随时向Apple提交错误报告,永远不会引起任何关注。