初學者關於記憶體的思考 不斷加深不斷更新中

2021-09-09 02:59:01 字數 3725 閱讀 8797

1、

從最簡單的說起,先看例子,看注釋:

-(void)fun1

-(void) fun2

-(void) fun3

-(void) fun4

在外面:

nslog(@"str2 final count:%d",[str2 retaincount]);//1 仍舊是1,因為由編譯器來負責管理(autorelease)

nslog(@"str3 final count:%d",[str3 retaincount]);//-1

由上面的**示例可以看出直接賦值跟用*with*方法賦值的區別。

stringwithformat裡面已經包含alloc和autorelease。確切地說,*with*方法都包含了alloc以及autorelease

2、在宣告為@property (nonatomic, retain) uialertview *alert時,這裡的retain不是擺設,而是retain了一次,這就剛好跟dealloc對應,在dealloc裡面release

計數器加1了。所以在還沒alloc之前,retaincount為1。

在.h中宣告alert為成員變數,並設為property的retain屬性  

uialertview *tmpalert = [[uialertview alloc]initwithtitle:tempstr

message:nil

delegate:self

cancelbuttontitle:@"取消"

otherbuttontitles:@"

確定",nil];

self.alert = tmpalert;

[tmpalert release];

[alert addsubview:view];

[alert show];

在上例子中,一般就這麼用,不要直接輕易去對alert進行alloc,這樣很容易出錯。常見的做法如上,設乙個臨時變數tmpalert,賦值給alert後就release掉。注意,是賦值

給self.alert,而不是alert。別忘了,self.alert = tmpalert 這句話等價於[alert release];alert = [tmpalert retain];(為什麼?)所以,為了避免額外的

錯誤,盡量在.h中宣告property/retain屬性,要賦值的時候就用self.***。

3、成員變數跟property不一定要對應存在,沒有成員變數只有property也是合法的,self.***訪問的就是property。

4、對乙個尚未分配記憶體的變數進行release是合法的。但是一旦你alloc+init了之後,就不能那麼隨便release。請看下面比較:

uialertview *alert =nil;

[alert release];//正確

uialertview *alert2 =[[uialertview alloc] init];

[alert release];

[alert release];//報錯

nsstring *str =nil;

[str release];//正確

nsstring *str2 =[[nsstring alloc] init];

[str2 release];

[str2 release];//正確!!!!!

可以看出,nsstring型別是個特列,不管你有沒有alloc分配記憶體給他,都可以隨時release。

從這個例子我們也可以看出,對於工程裡面的成員變數,不應該隨意去設@property屬性,因為這樣會暴露給別的類。但是這時候會有這樣的煩惱,沒有了(retain),似乎後面的記憶體管理會變得麻煩些。所以產生了另外一種方式,在.m檔案裡面,凡是用該成員變數(假設為a)的地方,首先要在init裡面把a置為nil,這是為了後面release的方便,不會出錯(對nil物件release是不出錯的)。然後凡是對該變數進行賦值的地方,都要先release,賦值完後再retain,養成習慣吧,兄弟。

5、@property、@synthesize

這兩個關鍵字是讓成員變數生成相應的setter、getter。setter裡面已經包含了必要的retain、release。平時我們用self.****就是訪問setter,而沒加self的就是訪問普通的成員變數。

看個例子:

@inte***ce photo : nsobject

nsstring* caption;

nsstring* photographer;

- (nsstring*) caption;//getter 

- (nsstring*) photographer;

- (void) setcaption: (nsstring*)input;//setter,注意其預設的名字set+***

- (void) setphotographer: (nsstring*)input;

@end

用@property實現簡化如下:

@inte***ce photo : nsobject

nsstring* caption;

nsstring* photographer;

@property (retain) nsstring* caption;

@property (retain) nsstring* photographer;

@end

這裡的retain意思是,setter應該對input進行retain。

原鏈結

- (void) dealloc

self.caption = nil;

self.photographer = nil;

[super dealloc];

6.下面介紹幾個個人比較容易混淆的東西,非常實用!先總說一下,原則是:

原則1:往陣列裡填東西或者刪除東西,陣列本身的引用計數不改變!!!!,變的是被拿去新增的元素,引用計數相應增減

原則2:往view新增subview或者removeview,superview本身引用計數都不改變!!!變的是被拿去新增的subview,引用計數相應增減

原則3:subview可分為兩種,一種是不需要控制的靜態view,一種是被設為成員變數長期控制的動態view。 假設subview新增到superview中,並且以後不打算做改變,則應這麼寫:

uiview *subview = new subview;//subview:1

//若是動態view,則是_subview = new subview;//subview:1

[superview addsubview:subview];//subview:2, superview:1

[subview release];//subview:1

靜態view:在dealloc中就不用再釋放了!因為大原則是「誰申請誰釋放」,你只申請了一次,自然只需要釋放一次。剩下的1個引用什麼時候減掉呢?當superview釋放的時候自己釋放掉!

動態view:若是動態view,則完全可以跟靜態view一樣,這樣的話dealloc裡面就是空空的,這也是可以的;另一種是在上述步驟中不做release操作,統統保留到dealloc中做

初學者關於記憶體的思考 不斷加深不斷更新中

1 從最簡單的說起,先看例子,看注釋 void fun1 void fun2 void fun3 void fun4 在外面 nslog str2 final count d str2 retaincount 1 仍舊是1,因為由編譯器來負責管理 autorelease nslog str3 fin...

CSS關於初學者的問題

原文 前幾天有個人退群了。起因很簡單,他問了乙個問題,沒人回答,於是說要退群,後來我看到了,給了個鏈結,說這個問題已經說過好多遍了,於是他就退了。開啟qq的群列表,我所在的技術群有5個,不包括原來參加過又退了的。另外,還去幾個論壇裡看。看得多了,忽然覺得有幾句話想說給初學者。97年,我開始接觸網路,...

iOS 初學者乙個關於記憶體管理的問題

先上 這個例子是 kenshincui 大神的。拿來學習使用。car.h import inte ce car nsobject pragma mark 屬性 pragma mark 車牌號 property nonatomic,copy nsstring no pragma mark 公共方法 p...