鍍金池/ 問答/iOS/ remove大量view時導致內存急劇增長該如何處理?

remove大量view時導致內存急劇增長該如何處理?

這是遍歷移除指定類型subview的方法:

- (void)refresh {
    for (UIView *view in self.subviews) {
        if ([view isMemberOfClass:[GoodListThemeView class]] || [view isMemberOfClass:[SingleGoodsThemeView class]]) {
            [view removeFromSuperview];
        }
    }
}

當調用此方法時,內存變化如下:

如果我將[view removeFromSuperview];這一句代碼注釋掉,則不會出現(xiàn)這種內存暴漲后又驟降的現(xiàn)象。

我猜測是那個for循環(huán)中產生了大量臨時對象導致的,于是我使用autoreleaserpool:

- (void)refresh {
    for (UIView *view in self.subviews) {
        @autoreleasepool {
            if ([view isMemberOfClass:[GoodListThemeView class]] || [view isMemberOfClass:[SingleGoodsThemeView class]]) {
                [view removeFromSuperview];
            }
        }
    }
}

但是內存還是突然暴漲然后下降。

誰能提供一點思路。。。

回答
編輯回答
蟲児飛
  1. 需要@autoreleasepool的作用,它的真實作用是 如果在包裹語句中創(chuàng)建了臨時變量,則可以提前釋放,顯然你使用情景并不符合這一原則,故無效
  2. for... in ...快速枚舉原則上是不應該對集合中的元素作修改的,也許可以試試塊遍歷(但我覺得應該差不太多,for in見到用的例子也挺多的),for循環(huán)不考慮是因為會導致多出一份臨時拷貝
  3. removeFromSuperview后并不代表這塊內存就釋放了,正確的說法是會在稍后的某個時間點釋放(一般是下一次事件循環(huán)),如果要及時釋放,可直接手動置空,view = nil;
2018年8月11日 11:17
編輯回答
離魂曲

[view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

2018年9月17日 11:05
編輯回答
九年囚

內存暴漲,我懷疑是removeFromSuperview方法延時生效造成的,可能在生效之前for循環(huán)在不斷執(zhí)行造成內存暴漲,解決方法還是手動置空吧

2017年4月8日 12:54
編輯回答
傲嬌范

我猜 for循環(huán)是removeFromSuperview方法是一個 異步耗時操作。 需要占內存比較大 , 想辦法移除完成一個后在移除下一個。搞一個同步之類的。

2017年2月14日 23:39
編輯回答
你的瞳

改成阻塞去做,棄用循環(huán),寫一個迭代器函數(shù)并遞歸自身

2018年1月19日 13:42
編輯回答
獨白

既然你看到內存暴漲了,你有沒有用 Instruments 看一下這個時間段的 Allocation trace?這段時間里有哪些對象被創(chuàng)建或者有哪些 malloc 發(fā)生?

2018年4月17日 00:42