菜鸟教程小白 发表于 2022-12-13 02:56:02

ios - 返回具有 Core Foundation 属性的 Objective-C 对象


                                            <p><p>我有一个方法,它返回一个名为“Credential”的自定义对象的 NSArray,它有两个属性:一个 NSString 和一个 CFDataRef。 </p>

<p>您已经注意到该对象有两种类型的属性,一个 NS Objective-C 属性和一个 Core-Foundation 属性。</p>

<p>对象在每次交互循环时都会被初始化,因为它会像这样填充 NSArray:</p>

<pre><code>cred = [ init];
cred.cn = ;
cred.serialNumber = CFDataCreateCopy(kCFAllocatorDefault, serialNumber);
</code></pre>

<p>当我运行分析器时,我收到以下消息:</p>

<pre><code>Object leaked: allocated object is not referenced later in this
execution path and has a retain count of +1
</code></pre>

<p>我假设发生此警告是因为我正在初始化一个 CF 对象并从该方法返回而不释放它,但是负责释放该对象的 new 应该
是调用该方法的代码。 </p>

<p>我应该在哪里调用 Credential 类的 CFDataRef 属性的 CFRelease?</p>

<p><strong>编辑:</strong></p>

<p>我正在使用 ARC,所以我将释放 NSString (cred.cn) 的责任留给他。但是,关于 CFDataRef (cred.serialNumber),我没有发布它,因为稍后我会从另一个类和部分代码中需要它。然后,我不确定如何管理它。当对象“凭证”被处置时,ARC 是否会释放它?如果没有,我可以覆盖 Credential 的 dealloc 方法来做 serialNumber 的 CFRelease 吗?</p>

<p>下面是初始化并返回 Credential 对象的 NSArray 的完整方法:</p>

<pre><code>- (NSArray *) retrieveIdentities
{
    CFArrayRef identities = NULL;
    NSMutableArray *returnIdentities = nil;
    OSStatus sanityCheck = NULL;

    const void *keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef, kSecReturnData, kSecReturnAttributes};
    const void *values[] = {kSecClassIdentity, kSecMatchLimitAll, kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue};
    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, sizeof(values)/sizeof(const void *), NULL, NULL);

    sanityCheck = SecItemCopyMatching(query, (CFTypeRef *)&amp;identities);

    if (query)
      CFRelease(query);
    if (sanityCheck == errSecItemNotFound)
      return nil;
    if (sanityCheck != noErr)
      @throw [ initWithName:@&#34;KeychainException&#34; reason:@&#34;ERROR_LISTING_IDENTITIES&#34; userInfo:, @&#34;osstatus&#34;, nil]];

    CFDictionaryRef result = NULL;
    CFStringRef summary = NULL;
    SecCertificateRef certificate = NULL;
    CFDataRef serialNumber = NULL;
    Credential *cred = nil;
    CFIndex resultCount = CFArrayGetCount(identities);

    returnIdentities = [ init];

    for (CFIndex i = 0; i&lt;resultCount; i++)
    {
      result = CFArrayGetValueAtIndex(identities,i);
      SecIdentityRef identity = (SecIdentityRef) CFDictionaryGetValue(result, kSecValueRef);

      if ((sanityCheck = SecIdentityCopyCertificate(identity, &amp;certificate)) != noErr)
             @throw [ initWithName:@&#34;KeychainException&#34; reason:@&#34;ERROR_EXTRACTING_CERTIFICATE&#34; userInfo:, @&#34;osstatus&#34;, nil]];

      CFTypeRef keyClass = CFDictionaryGetValue(result, kSecAttrKeyClass);
      if ([[(__bridge id)keyClass description] isEqual:(__bridge id)(kSecAttrKeyClassPrivate)])
      {
            summary = SecCertificateCopySubjectSummary(certificate);
            serialNumber = CFDataCreateCopy(NULL, CFDictionaryGetValue(result, kSecAttrSerialNumber));
            cred = [ init];
            cred.cn = ;
            cred.serialNumber = CFDataCreateCopy(kCFAllocatorDefault, serialNumber);
            ;

            if (summary)
                CFRelease(summary);

            if (serialNumber)
                CFRelease(serialNumber);
      }
    }

    if (certificate)
      CFRelease(certificate);


    return returnIdentities;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>如果使用 CF 函数创建的字符串意味着您拥有它,您应该将所有权转移给 ARC。目前,您只是桥接对 ARC 的引用,不会获得所有权。</p>

<p>对于数据,你需要重写<code>dealloc</code>并在数据上调用<code>CFRelease</code>。</p>

<hr/>

<p>分析仪并不完美。有些事情它觉得很困难,所以它会谨慎行事并告诉你可能有问题。</p>

<p>可以肯定的是,尤其是在泄漏和内存管理方面,您应该使用 <code>Instruments</code> 来检查发生了什么。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 返回具有 Core Foundation 属性的 Objective-C 对象,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/17319590/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/17319590/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 返回具有 Core Foundation 属性的 Objective-C 对象