1.ARC下用 @autoreleasepool {}主要還是為了避免內存峰值。簡單點的說在{}中存放的對象會在稍后的某個時刻釋放掉
(1)在自動釋放池@autoreleasepool{}中alloc一個對象后(如p1),仍然需要用[p1 autorelease];只是這個語句和[p1 release];不同,后者表示把p1的retainCount-1,而前者僅僅表示把p1放到自動釋放池中返回一個self,自動釋放池結束銷毀時,統一對里面的對象引用計數retainCount-1。
(2)@autoreleasepool{}可以隨意創建,也可以嵌套使用。
(3)不管這個對象是在自動釋放池內還是外創建的,只要在自動釋放池內寫一個[p1 autorelease];p1就會被放到自動釋放池中。注意autorelease是一個方法,且只有在自動釋放池中使用才有效。
(4)如果把一個對象重復加到自動釋放池如[p1 autorelease];[p1 autorelease];,那么會出錯。原因是:加載幾次,屆時自動釋放池就會用[p1 release];釋放幾次,但是由於這兩個加載的對象其實是一個對象同樣地址,所以第一次自動釋放正確,第二次自動釋放時發現已經被釋放了,所以p1就變成了野指針。
(5)以下是自動釋放池嵌套的使用規則和注意點。
#import <Foundation/Foundation.h>
#import "Person.h" int main(int argc, const char * argv[]) { Person *p1=[[Person alloc]init]; @autoreleasepool { @autoreleasepool { [p1 autorelease]; }//在執行到此處時,p1被自動釋放 } //以下代碼有錯誤 @autoreleasepool { [p1 autorelease];//此時p1被加入進來 @autoreleasepool { [p1 autorelease];//被重復加載進來,但仍然同一個 }//此處,p1被自動釋放了,所以第一次加進來的那個也被釋放了,因為是同一個對象 }//所以此處在調用[p1 release];時就出現報錯:野指針 return 0; }
(6)@autoreleasepool的應用:如果需要在方法中創建對象,並把這個對象作為返回值,那么可以在這個方法中使用[*** autorelease];把它加入到自動釋放池中,否則,直接用[*** release];來匹配alloc的話,在該方法中就已經把這個對象alloc和release了一遍相當於釋放了,那么所謂的返回對象返回的時一個野指針(沒有指向任何對象)。當然,調用這個方法的代碼頁需要寫在自動釋放池作用域內才生效。
(7)接上面。返回對象的那個方法中,創建對象不建議直接用類名,而是用self,否則如果存在子類調用會崩潰。如Car *car1=[[self alloc]init];
(8)其實諸如NSString *str1=[NSString stringWithFormat:@"%@",@"hello"];也是調用了一個方法,並且返回了一個字符串對象。比照(6)和(7)我們得知這個stringWithFormat應該也是順便返回了一個autorelease。
(9)在ARC機制中,我們用@property聲明的成員變量,建議用strong代替之前手動管理內存時的retain,雖然后者仍然可以使用。因為我們在ARC中內存管理就是看是否有強指針指向對象,如有就不回收,如沒有就回收。所以強指針是strong,相反是weak。而基本數據類型我們還是習慣用assign。
(10)雖然Xcode提供了非ARC轉換成ARC的,很少有把整個非ARC轉換成ARC的。如果我們導入第三方庫時,需要非ARC和ARC共存,即我們系統默認是ARC,我們需要讓系統不要去管這個非ARC的第三方庫,如下設置:雙擊響應的.m文件,輸入-fno-objc-arc回車即可。
(11)順便,當出現兩個類循環引用的話(也就是A要包含B,B要包含A,即A對象要作為B的變量,B對象要作為A的變量),只需要把一方的strong改成weak,並且在響應的.h文件中把#import ".h"改成Class ***。如果因為改成Class ***而無法使用那個類的方法的話,只需要在它的.m文件中#import“.h”文件即可,這個因為不是在.h文件中導入所以不沖突。
注意:利用webview加載gif圖時,左右來回滑動導致內存暴漲,用了
@autoreleasepool {
for (UIView *subview in self.welcomeScr.subviews) {
if ([[subview class]isSubclassOfClass:[UIWebView class]]) {
[subview removeFromSuperview];
}
}
NSInteger index= self.welcomeScr.contentOffset.x/ScreenW;
NSInteger count = index+1;
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%ld",index+1] ofType:@"gif"];
NSData *gifData = [NSData dataWithContentsOfFile:path];
UIWebView *webView = [self createWebViewWithFrame:CGRectMake(ScreenW * index ,0,ScreenW,ScreenH)];
[webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
[self.welcomeScr addSubview:webView];
}
之后,內存有些變小,但是減下來的內存只有1~2MB,沒有比增長的多,更沒有完全釋放掉
webview的內存釋放方法還需要研究。。。。。。。