@property 的本質是生成setter方法和getter方法以及一個帶下劃線的成員變量,經過autosynthesis添加到類中的。ios
一般的關鍵字爲:objective-c
nonatomic & atomicsegmentfault
這是表明原子性 可是atomic不能徹底保證線程安全 它只保證了setter和getter方法的線程安全,具體的狀況:當A線程進行寫操做的時候,B線程會等待。當A線程寫完,B線程進行寫操做,而後A線程讀取的將是B線程中的值,若是C線程在A線程讀寫前將對象release了還會形成程序崩潰api
strong & retain數組
strong至關於ARC下的retain 會強引用對象 使得對象的引用計數加一緩存
weak & assign安全
assign多被用來修飾基本數據類型,是指針賦值,不會對引用計數操做,使用以後不會自動置nil,可能會致使野指針。A對象的指針賦值給B,此時B只是保存了A的指針,不會持有A,因此當A被釋放的時候再訪問B可能會出現野指針錯誤。bash
weak表示弱引用,它既不會設置新值,也不會保存舊值。不會對引用計數操做,當指向的對象被釋放以後,自身也會被置nil多線程
copy異步
copy是對對象的引用計數加一,它對應的setter方法不會保存新值,而是將其拷貝一份,一般NSString以及具備可變類型的集合類型可使用copy修飾,拷貝一份出來,以保證不會再使用的過程當中被其餘地方的操做所改變
block也使用copy來修飾,這是MRC遺留下的傳統,提示開發者block是從棧上覆制到堆上的。
readwrite&readonly
讀寫,只讀
setter= & getter=
指定setter方法和getter方法
默認
基本數據類型默認是assign, atomic,readwirte
對象類型strong,atomic, readwrite
@synthesize 自動生成setter getter方法
@dynamic不須要編譯器生成,手動生成
默認是@synthesize var = _var
拷貝的本質是生成一份獨立的副本
對不可變對象來講 copy是淺拷貝,由於該對象自己就是不可變的了。而mutablecopy是深拷貝由於須要拷貝出來一份可變的對象,因此須要進行深拷貝,拷貝內存中的內容。
對可變對象來講,copy和mutable拷貝都是深拷貝,copy生成的對象是不可變的,mutablecopy會生成可變對象
自定義對象想要進行copy操做須要實現NSCopying
協議
實現copyWithZone
或者mutableCopyWithZone
方法
- (id)copyWithZone:(NSZone *)zone {
Person *p = [[Person allocWithZone:zone] init];
//屬性也要拷貝賦值
p.name = [self.name mutableCopy];
p.age = self.age;
return p;
}
複製代碼
若是Person中有其餘自定義對象,那麼該自定義對象也須要實現遵循並實現 NSCopying
協議。
class_isMetaClass
來驗證某個類是否是元類,其本質是一個 objc_class 的結構體。+ initialize
第一次初始化這個類以前調用,咱們經常使用來初始化靜態變量,是runtime負責的。+load
方法會在加載類的時候就被調用,也就是 ios 應用啓動的時候,就會加載全部的類,就會調用每一個類的 + load 方法。load經過指針直接找到函數地址直接調用沒有經過消息機制可使用Category爲類添加新方法,使用Category爲類添加新方法在必定程度上比使用繼承添加方法的釋放耦合度低。
category是不支持直接使用屬性的,能夠經過runtime的屬性綁定來實現。聲明一個屬性,實現setter和getter方法。在setter方法中使用objc_setAssociatedObject
第二個參數標記能夠用``@selector([getter method name]),getter方法中使用
objc_getAssociatedObject獲取屬性值,第二個參數使用
_cmd`
category 中實現的方法是在運行時添加到類中的。category是按照編譯順序排列的,因此後編譯的cat中取出的方法、屬性和協議列表,分別放在mlist、proplists和protolists的最前面。
block的本質是封裝了函數調用和函數調用環境的OC對象
Block對變量的捕獲:
block類型
MRC下 當block訪問了auto類型變量的時候是stackblock 其餘狀況下是globalblock
ARC下會將stackblock從棧上copy到堆上,固然這是編譯器幫咱們作的
ARC下的block會在一下狀況自動調用copy方法
對象類型的捕獲
__weak
ARC下一般使用__weak
來解決block的循環引用問題,使用它修飾的對象在被block捕獲的時候,在block內部也會使用__weak
來修飾,而使用__weak
修飾的對象會被弱引用。
__block
在block內部修改auto變量的時候一般會報錯,這個時候須要使用__block
修飾。__block
修飾的變量,在block內部會生成一個結構體,結構體中存放有isa指針__forwarding
指針,變量等信息,當改變變量的值得時候會經過__forwarding
指針找到這個結構體,改變其中變量的值。
_NSSetIntValueAndNotify
函數,它會在賦值以前調用willChangeValueForKey
,以後調用didChangeValueForKey
來監聽值得改變。setKey
,_setKey
的順序查找setter方法,若是找到則直接調用設置值,找不到則查看+ (BOOL)accessInstanceVariablesDirectly
方法的返回值,若是返回值是NO則調用setValue:forUndefinedKey
方法,若是沒有實現會拋出異常。若是是YES,則會按照_key
,_isKey
,key
,isKey
的順序查找成員變量賦值getKey
、key
、isKey
、_key
的順序查找對應的方法,若是找到則展開調用,若是找不到那麼查看+ (BOOL)accessInstanceVariablesDirectly
返回值,YES的話會按照_key
,_isKey
,key
,isKey
的順序查找成員變量,返回NO的話就會調用- (id)valueForUndefinedKey:(NSString *)key
,若是沒有實現會拋出異常+ (BOOL)accessInstanceVariablesDirectly
默認爲YESiOS 使用引用計數的方式管理內存,內存管理的原則是誰建立,誰釋放 。 誰引用,誰管理
使用new、alloc、copy或者mutable copy,引用計數爲初始值1,再使用retain的話,引用計數爲+1,使用release或者autorelease會使引用計數-1。
自動釋放池,OC對象調用autorelase方法以後,會將對象放到離本身最近的自動釋放池內,Run Loop在每一個事件循環結束後會去自動釋放池,會將釋放池內全部的對象都作一次release操做。
MRC下的setter方法
先釋放舊值再引用新值
- (void)setAge:(NSString *)age {
if (_age != age) {
[_age release];
[age retain];
_age = age;
}
}
複製代碼
iOS的多線程方案:
performSelector:onThread...
dispatch_queue_cretate
建立的,讀寫操做的時候可使用柵欄函數隔離寫操做。首先會在方法緩存中查找方法的實現,若是沒有找到則查找父類的實現,父類沒有實現會進入動態方法解析,爲該類添加一個方法的實現。若是動態方法解析尚未實現,那麼會進入消息轉發,將消息轉發給一個能夠相應該方法的target。若是這一步尚未實現則會進行方法簽名,返回一個方法簽名,並調用forwardInvacation
返回一個target處理該消息,若是尚未實現則會報方法找不到錯誤。
首先會通知監聽者Observers:即將處理Timers
通知監聽者Observers:即將處理Sources
處理blocks
處理source0,若是處理完了會再次處理blocks
若是存在source1,則跳到handle_msg處理,若是沒有則通知監聽器即將進入休眠
休眠時期等待消息來喚醒當前線程
若是有消息喚醒則進入handle_msg處理計時器,gcd,source1這些信息
再次處理blocks
獲取返回值retVal
進入do-while()
,若是retVal == 0
則循環持續進行。不然返回給CFRunLoopRunSpecific
函數,退出RunLoop
visiableCells
中全部cell移入reusableTableCells
,visiableCells
清空。cellForRowAtIndexPath
調用後,再把reuse
的cell從reusableTableCells
取出來,放入到visiableCells
。reusableTableCells
爲空,那麼cellForRowAtIndexPath
調用後,是新建立cell,新的cell加入到visiableCells
。老的cell移出visiableCells
,加入到reusableTableCells
client向server發送請求https://baidu.com,而後鏈接到server的443端口。
服務端必需要有一套數字證書,能夠本身製做,也能夠向組織申請。區別就是本身頒發的證書須要客戶端驗證經過,才能夠繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面,這套證書其實就是一對公鑰和私鑰。
傳送證書 這個證書其實就是公鑰,只是包含了不少信息,如證書的頒發機構,過時時間、服務端的公鑰,第三方證書認證機構(CA)的簽名,服務端的域名信息等內容。
客戶端解析證書 這部分工做是由客戶端的TLS來完成的,首先會驗證公鑰是否有效,好比頒發機構,過時時間等等,若是發現異常,則會彈出一個警告框,提示證書存在問題。若是證書沒有問題,那麼就生成一個隨即值(祕鑰)。而後用證書對該隨機值進行加密。
傳送加密信息 這部分傳送的是用證書加密後的祕鑰,目的就是讓服務端獲得這個祕鑰,之後客戶端和服務端的通訊就能夠經過這個隨機值來進行加密解密了。
服務段加密信息 服務端用私鑰解密祕密祕鑰,獲得了客戶端傳過來的私鑰,而後把內容經過該值進行對稱加密。
傳輸加密後的信息 這部分信息是服務端用私鑰加密後的信息,能夠在客戶端被還原。
客戶端解密信息
客戶端用以前生成的私鑰解密服務端傳過來的信息,因而獲取瞭解密後的內容。
上述文字出自HTTP和HTTPS協議,看一篇就夠了