核心基础:为什么 LLVM 分析器报告调用者不拥有使用 *Create* 函数创建的对象?

Core Foundation: why LLVM analyzer report that caller doesn't own object created with *Create* function?

根据 The Create Rule,我创建了自己的 "constructor" - CFStringCreateFromGoString。它的名称中包含 "Create"。我希望如果我调用 CFStringCreateFromGoString 那么我拥有返回的对象。

但根据 LLVM 静态分析器,这并不完全正确,在某些情况下我会收到警告 Incorrect decrement of the reference count of an object that is not owned at this point by the caller - 请参阅 1.h。在其他没有警告的情况下 - 请参阅 2.h.

来自common.h

CFStringRef CFStringCreateFromGoString(_GoString_ str) {
    return CFStringCreateWithBytes(NULL, (UInt8*)_GoStringPtr(str), (CFIndex)_GoStringLen(str), kCFStringEncodingUTF8, false);
}

来自1.h

CGRect _GetTextLineGeometry(CGContextRef context, _GoString_ str, CTFontRef font) {
    CFStringRef _str = CFStringCreateFromGoString(str);
    CGRect r = GetTextLineGeometry(context, _str, font); // no warning if I remove this line
    CFRelease(_str); // warning here
    return r;
}

来自2.h

CTFontRef _CreateFontFromFile(_GoString_ path, struct FontSpec spec) {
    CFStringRef _path = CFStringCreateFromGoString(path);
    CTFontRef r = CreateFontFromFile(_path, spec);
    CFRelease(_path); // no warning
    return r;
}

有人可以解释一下 1.h2.h 之间的区别吗?

更新 0

谢谢马特的评论。 问题出在 GetTextLineGeometry - 这个函数错误地执行了 CFRelease(_str)。现在我没有警告。 但我不明白为什么警告在 _GetTextLineGeometry 而不是 GetTextLineGeometry?

name 组件 "Create" 没有任何魔法;这只是约定俗成的问题。因此,就此而言,是 "ownership".

的概念

所以忘记所有这些,只考虑保留计数。

静态分析器不像你我这样的普通人,它可以看到你所有的代码,并且可以计数。它正在计算此对象的保留和释放。当我们在您的第一个示例中到达 CFRelease(_str) 时,您之前已经释放了同一个对象,导致其保留计数降至零;所以此时你正在执行过度释放。因此,此时静态分析器会标记您。

现在让我们回过头来,站在"ownership"的角度再想一想。只有某个东西的 "owner" 才能释放它;这就是 "ownership" 的意思。但是静态分析器非常愿意让您转让所有权,如果您知道自己在做什么的话。因此,如果您想通过在 GetTextLineGeometry 中发布来 "take ownership",那么使用静态分析器就可以了。但是当我们到达 CFRelease(_str) 时,那是 second "owner" — 而这不是板球。因此,静态分析器再次在此处.

标记您