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以及autorelease2、在宣告為@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...