使用ARC时,iOS NSString stringWithString会导致内存泄漏

时间:2015-11-04 12:09:42

标签: ios memory-leaks nsstring uilocalnotification nsnotificationcenter

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

- (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。有人可以帮助找到它的解决方案吗?感谢。

enter image description here

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

- (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'相互保留?

1 个答案:

答案 0 :(得分:0)

无需对传入的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];
    }
}

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