oc的內(nèi)存管理其實(shí)就是引用計(jì)數(shù)的管理(refrence count),需要時(shí)分配一段內(nèi)存空間允乐,用完釋放矮嫉。
一、關(guān)鍵詞:屬性牍疏,成員變量蠢笋,點(diǎn)語法,set和get方法鳞陨,下劃線變量昨寞,局部變量
1. 使用property的時(shí)候,同時(shí)重寫set get方法,編譯報(bào)錯(cuò)援岩?歼狼??
問題:使用property的時(shí)候享怀,同時(shí)重寫set get方法會(huì)報(bào)錯(cuò)羽峰,如
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController{
}
@property (nonatomic, copy) NSString *name;
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
單獨(dú)重寫任意一個(gè)方法都不會(huì)報(bào)錯(cuò),但是同時(shí)重寫的話凹蜈,會(huì)報(bào)錯(cuò)限寞!
主要是因?yàn)楫?dāng)你重寫了get和set方法之后@property默認(rèn)生成的@synthesize就不會(huì)起作用了,這也就意味著你的類不會(huì)自動(dòng)生成出來實(shí)例變量了仰坦,你就必須要自己聲明實(shí)例變量,如下修改(添加成員變量聲明):
這時(shí)就不會(huì)報(bào)錯(cuò)履植,OK!
2. iOS OC聲明變量 在@interface花括號(hào)中與使用@property的區(qū)別悄晃?玫霎??
摘自網(wǎng)絡(luò)妈橄,感謝網(wǎng)友分享庶近!
iOS OC聲明變量 在@interface括號(hào)中與使用@property的區(qū)別
- 方式一:直接在@interface中的大括號(hào)中聲明。
@interface MyTest : NSObject{
NSString *mystr;
} - 方式二:在@interface中聲明眷蚓,然后再在@property中聲明鼻种。
@interface MyTest : NSObject{
NSString *_mystr;
}
@property (strong, nonatomic) NSString *mystr;
隨后在.m文件中加入
@synthesize mystr = _myStr; - 方式三:直接用@property聲明
@interface MyTest : NSObject{
}
@property (strong, nonatomic) NSString *mystr;
隨后在.m文件中加入@synthesize mystr = _myStr;
首先方式一和方式三的區(qū)別:
方式一聲明的成員變量只能在自己類內(nèi)部使用的,而不能在類的外部使用(也就說通過 類名. 點(diǎn)的方式是顯示不出來的)沙热;
方式三則相反叉钥,它可以在類的外部訪問,在類的內(nèi)部可以通過下劃線+變量名或者self.變量名的方式來訪問篙贸。
方式二的寫法是一種過時(shí)的聲明變量的方式投队,xcode在早期@systhesize沒有自動(dòng)合成屬性器之前,需要手寫getter與setter方法爵川,下劃線從風(fēng)格上表明這是類的內(nèi)部變量敷鸦,要是需要直接使用變量則需要使用get或者set的方式。
在XCode目前有了自動(dòng)合成屬性器后寝贡,編譯器會(huì)自動(dòng)幫我們生成一個(gè)以下劃線開頭的的實(shí)例變量扒披,所以我們不必去同時(shí)聲明屬性與變量。 我們可以直接用@property的方式來聲明一個(gè)成員屬性圃泡,在.m文件中使不使用@systhesize都無所謂谎碍,xcode會(huì)自動(dòng)幫你生成getter與setter。
個(gè)人比較喜歡使用方式三的方式洞焙,這是是蘋果開發(fā)模板所推薦的,也可以在.m文件中不加@systhesize看個(gè)人喜好。
3. 點(diǎn)語法本質(zhì)是一個(gè)方法的調(diào)用澡匪,具體的呢熔任??唁情?
self.age = 3;(調(diào)用set方法)
相當(dāng)于[self setAge:3];
age = self.age;(調(diào)用get方法)
此處的self.age相當(dāng)于[self age];
@property(nonatomic,strong)NSString *name;
此處的()號(hào)里省略了readwrite疑苔,@property關(guān)鍵字 會(huì)自動(dòng)生成set和get方法。
@property(nonatomic,strong,readOnly)NSString *name;
只生成get方法甸鸟,不能set
4. 局部變量惦费,如下設(shè)置tableview數(shù)據(jù)源,數(shù)據(jù)不會(huì)展示:
ArrayDataSource *datasource = [[ArrayDataSource alloc]initWithItems:self.datalist cellIdentifier:@"MyCell" configureCellBlock:^(id cell, id item) {
[cell cellWithModel:item];
}];
self.tb.dataSource = datasource;
如下改OK:
@property(nonatomic, strong)ArrayDataSource *myDatasource;
self.myDatasource = [[ArrayDataSource alloc]initWithItems:self.datalist cellIdentifier:@"MyCell" configureCellBlock:^(id cell, id item) {
[cell cellWithModel:item];
}];
總結(jié):局部變量的一個(gè)特點(diǎn)就是抢韭,當(dāng)它超過作用域時(shí)薪贫,就會(huì)被自動(dòng)釋放。
二刻恭、alloc+init初始化瞧省,new初始化,@初始化
1. alloc+init初始化和new的區(qū)別鳍贾?鞍匾??
基本上一樣骑科,也有差別橡淑,詳情可以百度。主要區(qū)別:
init初始化可以用init打頭的其它方法咆爽,而new只能是init方法梁棠。
2. @初始化(iOS -- NSDictionary 兩種初始化方式的區(qū)別)
方法1: [NSDictionary dictionaryWithObjectsAndKeys:<#(id), ...#>, nil]
方法2: NSDictionary dic = @{@"key":value}
區(qū)別在哪里?
區(qū)別就在第二種初始化方法 NSDictionary
dic = @{@"key":value}
如果value是為nil 必將引發(fā)崩潰:
'NSInvalidArgumentException', reason: '* -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]
意思就是說使用[__NSPlaceholderDictionary initWithObjects:forKeys:count:]這個(gè)初始化方法伍掀,發(fā)現(xiàn)keys count和objcects的個(gè)數(shù)不匹配了
如何規(guī)避掰茶?
在使用@{@”key”:value} 這種方式初始化的時(shí)候,一定要對(duì)value做是否為nil的判斷蜜笤,如果為ni濒蒋,就不要加入Dictionary
或使用標(biāo)準(zhǔn)的初始化方法:
NSDictionary dictionaryWithObjectsAndKeys:value1,@"v1",value2,@"v2",value3,@"v3", nil];
或其它的幾個(gè)初始化方法進(jìn)行初始化,這樣如果value為nil就不會(huì)加入字典把兔,使用 objectForKey:取出來的對(duì)象就會(huì)為nil對(duì)象沪伙,不會(huì)引發(fā)崩潰。
End
待寫:
1 strong县好,weak围橡,assign,copy缕贡,retain等關(guān)鍵字
2 runtime
runtime翁授,property拣播,synthesize,dynamic理論知識(shí)講解參考鏈接
附:
- performSelector調(diào)用和直接調(diào)用區(qū)別???(引用自網(wǎng)絡(luò))
performSelector調(diào)用和直接調(diào)用區(qū)別
下面兩段代碼都在主線程中運(yùn)行,我們?cè)诳磩e人代碼時(shí)會(huì)發(fā)現(xiàn)有時(shí)會(huì)直接調(diào)用收擦,有時(shí)會(huì)利用performSelector調(diào)用贮配,今天看到有人在問這個(gè)問題,我便做一下總結(jié)塞赂,
[delegate imageDownloader:self didFinishWithImage:image];
[delegate performSelector:@selector(imageDownloader:didFinishWithImage:)withObject:self withObject:image];
1泪勒、performSelector是運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)去找方法的,在編譯時(shí)候不做任何校驗(yàn)宴猾;如果直接調(diào)用編譯是會(huì)自動(dòng)校驗(yàn)圆存。如果imageDownloader:didFinishWithImage:image:不存在,那么直接調(diào)用 在編譯時(shí)候就能夠發(fā)現(xiàn)(借助Xcode可以寫完就發(fā)現(xiàn))仇哆,但是使用performSelector的話一定是在運(yùn)行時(shí)候才能發(fā)現(xiàn)(此時(shí)程序崩潰)沦辙;Cocoa支持在運(yùn)行時(shí)向某個(gè)類添加方法,即方法編譯時(shí)不存在税产,但是運(yùn)行時(shí)候存在怕轿,這時(shí)候必然需要使用performSelector去調(diào)用。所以有時(shí)候如果使用了performSelector辟拷,為了程序的健壯性撞羽,會(huì)使用檢查方法- (BOOL)respondsToSelector:(SEL)aSelector;
2、直接調(diào)用方法時(shí)候衫冻,一定要在頭文件中聲明該方法的使用诀紊,也要將頭文件import進(jìn)來。而使用performSelector時(shí)候隅俘,可以不用import頭文件包含方法的對(duì)象邻奠,直接用performSelector調(diào)用即可。