【问题标题】:Potential leak of an object allocated on line …在线分配的对象的潜在泄漏......
【发布时间】:2012-07-21 15:28:46
【问题描述】:

我正在获取联系方式,但我的 shouldContinueAfterSelectingPerson 方法存在内存问题。我在几周前遵循了一个教程,但是现在当我单击产品-> 分析时,我在这 3 行上得到“在线分配的对象的潜在泄漏”:

[lastName setText:(__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty)];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateOfBirth setText:birthday];

当我点击这些错误时(虽然第三行只有 2 号):

  1. 调用函数 'ABRecordCopyValue' 会返回一个具有 + 1 保留计数的 Core Foundation 对象

  2. 对象泄露:分配的对象在此执行路径的后面没有被引用,并且保留计数为 + 1

完整代码如下:

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

[firstName setText:(__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty)];

[lastName setText:(__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty)];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MMMM d, yyyy"];
birthday = [dateFormatter stringFromDate:(__bridge NSDate *)ABRecordCopyValue(person, kABPersonBirthdayProperty)];
[dateOfBirth setText:birthday];

是否有解决此问题的方法?我修复它有多重要?我的代码中还有另一个潜在的对象泄漏。

最后一点:我正在使用 ARC。

【问题讨论】:

  • 你发布过 dateFormatter 吗?
  • @trumpetlicks 我正在使用 ARC,所以我无法发布任何内容。把 dateFormatter = nil;使用后也没有删除警告
  • 变量“生日”是怎么来的,你在哪里声明它,等等...?
  • 名字、姓氏和生日都是我在 .m 文件顶部的所有 (at)synthesise 属性下声明的 NSString。然后我尝试用(at)属性(非原子,保留)将它们放入.h,但没有任何区别。

标签: iphone xcode memory


【解决方案1】:

你想要这个:

[lastName setText:(__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty)];

您看到来自分析器的警告的原因是 ABRecordCopyValue 返回一个带有 +1 保留计数的 CFStringRef。然后,您将转换为 NSString*,但对 ARC 说不要拥有该对象的所有权。这意味着它不会自动为您添加版本。因此,您需要告诉 ARC 在使用 __bridge_transfer 完成转换为 Objective-C 对象域期间取得所有权。

你也可以这样做:

CFStringRef string = ABRecordCopyValue(person, kABPersonLastNameProperty);
[lastName setText:(__bridge NSString *)string];
CFRelease(string);

【讨论】:

  • 太棒了!感谢您的回答和背后的原因!非常感谢:)
  • 没问题:-)。 ARC 很棒,但确实有一些你应该注意的错综复杂的地方。使用分析仪做得很好 - 它是你的朋友!
【解决方案2】:

由于函数返回新对象(它们的名称中有副本),您需要以某种方式释放这些对象。

这可以通过调用适当的方法来释放它,或者使用__bridge_transfer而不是__bridge来完成,它指示ARC接管内存管理并在需要时释放它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 2012-01-17
    相关资源
    最近更新 更多