【问题标题】:ios - possible memory leaks with nsmutablearray not deleted?ios - 未删除 nsmutablearray 可能导致内存泄漏?
【发布时间】:2014-06-20 16:48:13
【问题描述】:

我是 iOS 开发的新手,在我的应用中看到一些奇怪的内存使用行为。

我正在使用 setupDataForPage 方法从服务器获取对象:

- (void)setupDataForPage:(int)page actionType:(NSString *)type success:(void (^)())callback 
{
__weak MyTableViewController *weakSelf = self;

// clearing image cache because feed contains a lot of images
[[SDImageCache sharedImageCache] clearMemory];
[[SDImageCache sharedImageCache] clearDisk];

MyHTTPClient *API = [MyHTTPClient new];

[API feedFor:page success:^(AFHTTPRequestOperation *operation, id data) {
    NSArray *data = [data objectForKey:@"data"];

    if ([data count] > 0) {
        // remove all objects to refresh with new ones
        if ([type isEqualToString:@"pullToRefresh"]) {
            [weakSelf.models removeAllObjects];
        }

        // populate data
        NSMutableArray *result = [NSMutableArray new];
        for (NSDictionary *modelData in data) {
            MyModel *model = [[MyModel alloc] initWithDictionary:modelData];
            [result addObject:model];
        }

        [weakSelf.models addObjectsFromArray:result];
        [weakSelf.tableView reloadData];
    }

    callback();
} failure:nil];
}

它在 viewDidLoad 中用于获取初始请求以及拉刷新和无限滚动:

- (void)viewDidLoad {
[super viewDidLoad];

__block int page = 1;
__weak MyTableViewController *weakSelf = self;

// initial load
[self setupDataForPage:page actionType:@"initial" success:^{ page += 1; }];

// pull to refresh
[self.tableView addPullToRefreshWithActionHandler:^{
    [weakSelf setupDataForPage:1 actionType:@"pullToRefresh" success:^{
        [weakSelf.tableView.pullToRefreshView stopAnimating];
    }];
}];

// infinite scrolling
[self.tableView addInfiniteScrollingWithActionHandler:^{
    [weakSelf setupItemsForPage:page actionType:@"infiniteScroll" success:^{
        page += 1;
        [weakSelf.tableView.infiniteScrollingView stopAnimating];
    }];
}];
}

我注意到,即使在返回相同数据的 pull to refresh 操作之后(我只是删除所有模型并再次添加它们),我的应用程序的内存使用量也从接近 19mb 增长到 24mb..

我希望更有经验的人查看这段代码,以确定它是否包含一些可能的内存泄漏。我是否应该在将NSMutableArray *result 变量分配给模型数组后以某种方式删除它?

谢谢!

【问题讨论】:

  • 这可能是因为在每个 pullToRefresh 中,您都在分配和初始化一个新数组。
  • @Morpheus 是 ARC 删除它吗?
  • 不要使用new数组,而是尝试在weakSelf.models中添加对象。在 for-in 循环中。

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


【解决方案1】:

首先,在这里使用@autoreleasepool

@autoreleasepool {
    NSArray *data = [data objectForKey:@"data"];

    if ([data count] > 0) {
        // remove all objects to refresh with new ones
        if ([type isEqualToString:@"pullToRefresh"]) {
            [weakSelf.models removeAllObjects];
        }

        // populate data
        NSMutableArray *result = [NSMutableArray new];
        for (NSDictionary *modelData in data) {
            MyModel *model = [[MyModel alloc] initWithDictionary:modelData];
            [result addObject:model];
        }

        [weakSelf.models addObjectsFromArray:result];
        [weakSelf.tableView reloadData];
    }
}

@autoreleasepool 允许您立即释放该范围内分配的每个对象。

这是使用它的完美情况;)

【讨论】:

  • 这是你的代码,只是@autoreleasepool { 在最后打开和关闭......有什么问题?
  • 我的意思是在[API feedFor:page success:^(AFHTTPRequestOperation *operation, id data) { ... 里面?
  • 好的 :) 添加了,看起来有点帮助,在 pullToRefresh 内存现在增加了 1Mb 之后,但仍在增加.. NSMutableArray *result = [NSMutableArray new]; 可能是它的原因吗?
  • 不,这是正常的,因为您将新数据添加到通用数组中,并且永远不会删除它,因此新数据,增加内存,完全正常 :) 。如果我的答案有效,请不要忘记选择最佳答案。谢谢大佬。
  • 谢谢!顺便说一句,@autoreleasepool 对我来说真的很有必要,因为我的应用正在使用 ARC?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 2021-06-14
  • 2013-04-24
  • 2016-08-15
  • 1970-01-01
  • 2014-04-19
相关资源
最近更新 更多