【问题标题】:iOS NSString stringWithString cause memory leak when using ARCiOS NSString stringWithString 在使用 ARC 时导致内存泄漏
【发布时间】:2016-02-04 22:17:11
【问题描述】:

我想在发布通知时传递一些数据,数据是包含本地通知信息的字典。

- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
NSString *uuid = [NSString stringWithString:notification.userInfo[@"UUID"]];
NSDictionary *infoDic = @{
                          @"UUID" :uuid
                          };
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
    [[NSNotificationCenter defaultCenter]
     postNotificationName:@"PopReminder"
     object:nil
     userInfo:infoDic];
}

}

通知类似于notification.userInfo = @{ @"UUID" : list.itemKey }

而list.itemKey是一个字符串,用来标识具体的列表。

NSUUID *uuid = [[NSUUID alloc] init]; NSString *key = [uuid UUIDString]; list.itemKey = key;

但是当使用 Leak 进行测试时,它显示了一个 NSString 对象导致内存泄漏。类方法如何导致内存泄漏并且它正在使用ARC。有人可以帮助找到解决方案吗?谢谢。

用另一种方式解决,但仍不清楚泄漏原因:

- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
NSString *uuid;
NSArray *lists = [YYList MR_findAll];
for (YYList *list in lists) {
    if ([list.itemKey isEqualToString:notification.userInfo[@"UUID"]]) {
        uuid = [list.itemKey copy];
    }
}
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
    [[NSNotificationCenter defaultCenter]
     postNotificationName:@"PopReminder"
     object:nil
     userInfo:@{
                @"UUID" :uuid
                }];
}

}

这样,效果很好。但是还是想知道为什么不能直接使用 [notification.userInfo[@"UUID"] copy] 来传递数据。在泄漏中,它表明这是一个泄漏周期,也许它是一个线索,表明我错过了一些东西。如果是这种情况,以哪种方式导致 UILocalNotification '通知' 和 NSNotification 'PopReminder' 相互保留?

【问题讨论】:

  • 使用 stringWithFormat,而不是 stringWithString
  • 是否需要新建字符串? copy @Geet 不要使用 stringWithFormat: 除非你真的有格式要处理...
  • 它正在将一个对象处理成字符串,因此此时您需要使用 stringWithFormat
  • stringWithString 方法返回一个自动释放的对象,但这与 ARC 无关。编辑您的问题以将您的代码显示为带有代码标签的文本。泄漏标记掩盖了代码,所以我不知道这些语句在做什么。
  • @Geet 问题说它已经是一个字符串了。它不是一种格式,并且 OP 并不要求将任意对象转换为其描述。即使 OP 是,最好明确地调用description 以使用@"%@" 的格式。 stringWithFormat 可能是可可中被滥用和误用最多的方法之一...

标签: ios memory-leaks nsstring uilocalnotification nsnotificationcenter


【解决方案1】:

对传入的userInfo进行任何重新处理的需求为零。您可以直接传递它。

与此同时,Instruments 告诉您,在那里创建的对象最终会泄露。这意味着捕获PopReminder 的人正在导致对象泄漏。在那里调查。虽然对您的任意[NSString stringWithString:] 的需求为零,但它并非无效。

以下内容:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"PopReminder"
         object:nil
         userInfo:notification.userInfo];
    }
}

... 是您提供的方法的完美、完整版本。

【讨论】:

  • 我也认为它可能与 NSString 方法无关,但与该通知的接收者有关。我会对此进行调查。谢谢。
猜你喜欢
  • 2012-08-10
  • 1970-01-01
  • 2011-06-26
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 2013-03-19
相关资源
最近更新 更多