如果使用imageNamed這個(gè)方法加載一些比較大的資源文件就容易崩潰兵多,從而引發(fā)了imageNamed生成的對象什么時(shí)候釋放?
使用imageNamed這個(gè)方法生成的UIImage對象,會在應(yīng)用的bundle中尋找圖片,如果找到,則Cache到系統(tǒng)緩存中,作為內(nèi)存的cache,而程序員是無法操作cache的,只能由系統(tǒng)自動(dòng)處理,如果我們需要重復(fù)加載一張圖片,那這無疑是一種很好的方式,因?yàn)橄到y(tǒng)能很快的從內(nèi)存的cache找到這張圖片,但是試想,如果加載很多很大的圖片的時(shí)候,內(nèi)存消耗過大的時(shí)候,就會會強(qiáng)制釋放內(nèi)存橄仆,即會遇到內(nèi)存警告(memory warnings)剩膘。由此看來[UIImage imageNamed:]只適合與UI界面中小的貼圖的讀取,而一些比較大的資源文件應(yīng)該盡量避免使用這個(gè)接口[UIImage imageWithContentsOfFile]解決掉這個(gè)問題盆顾。
[[UIImageView alloc] init]還有一些其他的 init 方法怠褐,返回的都是 autorelease 對象。而 autorelease 不能保證什么時(shí)候釋放椎扬,所以不一定在引用計(jì)數(shù)為 0 就立即釋放惫搏,只能保證在 autoreleasepool 結(jié)尾的時(shí)候釋放。
for (int i = 0; i < 1000; i++) {
UIImage* image = [UIImage imageNamed:@"some_image"];
// 對 image 進(jìn)行一些處理蚕涤,比如存文件什么的
}
執(zhí)行這段代碼就會看到內(nèi)存越增越大筐赔,容易導(dǎo)致崩潰。而在每一次循環(huán)結(jié)束的時(shí)候揖铜,UIImage 引用都為0了茴丰,不過系統(tǒng)不會把它立即釋放掉;循環(huán)次數(shù)多了內(nèi)存就爆掉了天吓。
為了解決這個(gè)問題贿肩,可以改成這樣:
for (int i = 0; i < 1000; i++) {
@autoreleasepool {
UIImage* image = [UIImage imageNamed:@"some_image"];
// 對 image 進(jìn)行一些處理,比如存文件什么的
}
}
這樣在每次循環(huán)結(jié)束的時(shí)候都會立即釋放 UIImage龄寞,也不會對內(nèi)存造成壓力了汰规。