oc 語法相對比較繁復,對比新興的python,swift,kotlin 是比較啰嗦的, 90年代的發(fā)明深受當時pascal ,basic的影響.
首先說明oc類相關的內(nèi)容
簡單的類使用
初始化一個類
//兩個方法效果其實一樣
UIImageView *bgImgV = [UIImageView new];
UIImageView *bgImgV = [[UIImageView alloc]init];
//調(diào)用類的方法
[bgImgV addSubview:_logoImgV];// addSubview為方法 _logoImgV為方法使用的參數(shù)
//獲取類的屬性
bgImgV.frame //用 "."調(diào)用
//設置類的屬性(2種方法)
bgImgV.alpha = 1;
[bgImgV setAlpha:1];
注意
1 ios 調(diào)用方法有時也叫發(fā)送消息,兩者是一個意思.
2 只用公用屬性才能被訪問.
3 只用公用屬性同時沒有設置readonly才能被修改.
4 通常鼓勵在.h文件內(nèi)聲明property,方便在使用是在外部調(diào)用.
屬性聲明
@property (nonatomic,strong)UIView *volumeBarView;
@property (nonatomic,copy)NSString *str;
@property (nonatomic,assign)int count;
為什么他們的修飾符都不同呢? 在工作中上炎,字符串用copy凡蚜,基本數(shù)據(jù)類型用assign悼瓮,控件用strong趋距。每當對象alloc,retain略步,strong谅猾,copy的時候映九,引用計數(shù)會加一,dealloc沃暗,頁面釋放時候會減一月洛,引用計數(shù)為零的時候內(nèi)存便會釋放。
1 strong表示變量指針是強持有類型,在賦值之后就會指向這個對象并且讓計數(shù)器加1
2 copy 就比較復雜,分為深拷貝和淺拷貝兩種. 使用copy 的初衷就是保持賦值后,不被數(shù)據(jù)來源的更改所影響.
我這樣說你就明白了 A->B A中的一個MutableString給B中的一個Property(NSString類型)賦值 首先是能接受的孽锥,父類可以接受子類嚼黔,如果是retain,僅僅是生成一個指針惜辑,計數(shù)器加一唬涧,然后指向那個MutableString。如果MString改變盛撑,B中那個跟著改變爵卒,因為是同一塊內(nèi)存區(qū)域。而選擇Copy相當于又生成了一個NSString撵彻,與A中的MutableString獨立钓株。
下面我想通過一個最簡單的例子來說明它們的區(qū)別:
首先我們來看看使用strong會出現(xiàn)什么樣的情況:
.h
@property (nonatomic, strong) NSString *name;
.m
NSMutableString *mStr = [NSMutableString stringWithString:@"奧特曼"];
self.name = mStr;
NSLog(@"用strong第一次得到的名字:%@", self.name);
[mStr appendString:@"2"];
NSLog(@"用strong第二次得到的名字:%@", self.name);
打印結果:
2017-04-07 16:20:10.138793 copyTest[2421:682898]用strong第一次得到的名字:奧特曼
2017-04-07 16:20:10.138884 copyTest[2421:682898]用strong第二次得到的名字:奧特曼2
結論:
通過上面的例子我們可以看出,我們在沒有直接修改 self.name 的情況下 self.name 卻被修改了陌僵,就好像一個人的名字怎么能沒有經(jīng)過自己同意就被修改呢轴合?我們的初衷只是想修改mStr,但是 self.name 卻被意外的修改了碗短,而這就是我們使用strong所不想看到的受葛,它會破壞程序的封裝性。(使用strong后 self.name 和 mStr 指向的是同一片內(nèi)存偎谁,所以修改其中一個值后兩個值就都變了)
那么使用copy又會得到什么結果呢总滩?下面是使用copy的例子:
.h
@property (nonatomic, copy) NSString *name;
.m
NSMutableString *mStr = [NSMutableString stringWithString:@"奧特曼"];
self.name = mStr;
NSLog(@"用copy第一次得到的名字:%@", self.name);
[mStr appendString:@"2"];
NSLog(@"用copy第二次得到的名字:%@", self.name);
打印結果:
2017-04-07 16:35:04.012589 copyTest[2428:685221]使用copy第一次得到的名字:奧特曼
2017-04-07 16:35:04.012676 copyTest[2428:685221]使用copy第二次得到的名字:奧特曼
結論:
這個例子中我們使用了copy修飾,mStr通過copy得到了一個新的對象賦值給 self.name 這樣我們再修改mStr就跟 self.name 沒關系了巡雨,只有直接對 self.name 進行賦值才能改變它的值闰渔,這樣就保證了程序的封裝性。
原子性
你一定也注意到了 nonatomic 關鍵詞,附上官方解釋:
atomic和nonatomic的對比
1铐望、atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作冈涧。
2茂附、atomic:系統(tǒng)生成的 getter/setter 會保證 get、set 操作的完整性督弓,不受其他線程影響营曼。getter 還是能得到一個完好無損的對象(可以保證數(shù)據(jù)的完整性),但這個對象在多線程的情況下是不能確定的愚隧,比如上面的例子蒂阱。
也就是說:如果有多個線程同時調(diào)用setter的話,不會出現(xiàn)某一個線程執(zhí)行完setter全部語句之前狂塘,另一個線程開始執(zhí)行setter情況蒜危,相當于函數(shù)頭尾加了鎖一樣,每次只能有一個線程調(diào)用對象的setter方法睹耐,所以可以保證數(shù)據(jù)的完整性辐赞。
atomic所說的線程安全只是保證了getter和setter存取方法的線程安全,并不能保證整個對象是線程安全的硝训。
3响委、nonatomic:就沒有這個保證了,nonatomic返回你的對象可能就不是完整的value窖梁。因此赘风,在多線程的環(huán)境下原子操作是非常必要的,否則有可能會引起錯誤的結果纵刘。但僅僅使用atomic并不會使得對象線程安全邀窃,我們還要為對象線程添加lock來確保線程的安全。
4假哎、nonatomic的速度要比atomic的快瞬捕。
5、atomic與nonatomic的本質(zhì)區(qū)別其實也就是在setter方法上的操作不同
在此你可以先留下印象,在學習多線程的時候會詳細講解.