【问题标题】:Memory leak when declaring NSString from ABRecordCopyValue从 ABRecordCopyValue 声明 NSString 时内存泄漏
【发布时间】:2012-04-15 13:59:33
【问题描述】:

我正在使用以下代码行...

NSString *clientFirstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

Xcode 上的“分析”功能表明这会导致潜在的内存泄漏。我根本没有发布 clientFirstName,因为我既没有 alloc 也没有 retain'd 它。

但是,我意识到 ABRecordCopyValue 可能不会返回对象,因为像 [NSMutableArray arrayWithArray:someArray] 这样的命令可能意味着我确实在创建一个我可以控制并且必须释放的新对象。

渴望听到想法......

【问题讨论】:

    标签: iphone objective-c ios memory-leaks abaddressbook


    【解决方案1】:

    任何类型的复制都会返回一个 retainCount 为 1 的对象,因此您需要通过 CFRelease() release 它。

    doc

    你有责任释放这个对象。

    【讨论】:

    • 是的 - 这行得通。还没有完全理解 CFRelease!
    • CFRelease() 与向对象发送release-消息相同。
    • @Jenox:从快速观察来看,我认为您的答案并不完全正确。我认为它是不完整的。没有什么私人的!
    • 你介意告诉我你认为不完整的地方吗?
    • @Jenox 如果我没记错的话,我认为你应该指定检查对象,如果对象不是nil,那么最好在对象上执行函数,因为执行没有意义release 用于 nil 对象。您应该特别指定这一点,因为 Ben Thompson 看起来是一个相当新的 Objective-C 程序员。希望这很好。 :)
    【解决方案2】:

    请参阅此链接。它和你的一样:

    NSString potential leak

    参考KennyTM的回答:

    ABMultiValueCopyValueAtIndex 是一个“复制”功能,如下 the "Create Rule"。 使用完毕需要调用CFRelease释放。

    NSString *contactEmail = (NSString *)ABMultiValueCopyValueAtIndex(emailInfo, 0);
    ...
    if (contactEmail != nil)
      CFRelease((CFTypeRef) contactEmail);
    

    使用CFRelease 释放您的对象clientFirstName

    添加以下代码:

    if(clientFirstName != nil)
    {
         CFRelease((CFTypeRef) clientFirstName);
    }
    

    注意:不要忘记检查clientFirstName 是否不为零。最好在对对象执行任何函数之前检查对象是否不是nil,因为这样可以避免潜在的崩溃,虽然不是在这种情况下,但在很多情况下

    编辑:

    正如@Dondragmer 在下面的其中一个 cmets 中所说:

    我觉得还是

    [clientFirstName release];
    

    应该能解决问题。

    如果您需要更多帮助,请告诉我。

    希望对你有所帮助。

    【讨论】:

    • 由于NSStringCFStringRef 是免费桥接的,因此调用[contactEmail release] 而不是CFRelease((CFTypeRef) contactEmail) 就足够了。两种语句的效果相同,但第一种更安全:您是否在 nil 对象上调用 Objective-C release 并不重要。
    • @Dondragmer: 没有冒犯你,但我仍然更喜欢在执行任何函数之前检查对象是否不是nil 的做法更好,因为它可以让我们避免潜在的崩溃一些案例。我也更喜欢第二个CFRelease((CFTypeRef) contactEmail)
    • @Dondragmer:也想问一下你为什么觉得[contactEmail release];更安全?我相信第二个是应该使用的。
    • 如果程序员出错并调用[contactEmail release]; 而不检查nil,它不会崩溃。在同样的情况下调用CFRelease((CFTypeRef) contactEmail); 会导致崩溃。只要内存没有被破坏,不崩溃比崩溃更安全。也可以在创建字符串后立即调用[contactEmail autorelease];,将分配和解除分配放在程序中的同一点。
    • @Dondragmer:好的,谢谢您的信息。我已经编辑了我的答案,并在答案的编辑部分添加了您的观点。感谢您的信息:)
    【解决方案3】:

    我不完全理解 ObjectiveC 引用计数的工作原理,但代码中的一个小更新修复了分析警告:

    之前:

    NSString *firstName = (__bridge NSString*) ABRecordCopyValue(person, kABPersonFirstNameProperty);
    

    之后

    NSString *firstName = (__bridge_transfer NSString*) ABRecordCopyValue(person, kABPersonFirstNameProperty);
    

    【讨论】:

      猜你喜欢
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 2012-10-29
      • 2014-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      相关资源
      最近更新 更多