iOS基礎
-
分類(Category)和類擴展(Class Extension)
分類(Category)
Category则奥,是表示一個指向分類的結構體的指針桑驱,其定義如下: typedef struct objc_category *Category; struct objc_category { char *category_name OBJC2_UNAVAILABLE; // 分類名 char *class_name OBJC2_UNAVAILABLE; // 分類所屬的類名 struct objc_method_list *instance_methods OBJC2_UNAVAILABLE; // 實例方法列表 struct objc_method_list *class_methods OBJC2_UNAVAILABLE; // 類方法列表 struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 分類所實現(xiàn)的協(xié)議列表 } 分類的結構體成員:分類名、分類所屬的類名佩迟、實例方法列表酬诀、類方法列表磺芭、分類所實現(xiàn)的協(xié)議列表。 發(fā)現(xiàn)是尖,該結構體包含了分類定義的實例方法與類方法意系,但結構體里沒有屬性列表。 注:(Category局限性上) 1.Category饺汹,原則上只能添加方法蛔添,不能添加屬性,實際上可以通過其他方式添加屬性首繁; 2.分類中可以寫 @property作郭,但不會聲明及實現(xiàn)setter/getter陨囊; 3.分類的優(yōu)先級最高弦疮,如果方法名與原有類同名,則會優(yōu)先調用分類中的方法蜘醋,優(yōu)先級順序 分類>本類>父類; 延伸問題: 為什么在分類中聲明屬性時運行不會報錯胁塞? or 為什么分類中使用@property仍然可以編譯通過? 答:一個類中使用@property聲明屬性压语,編譯器會自動生成 _成員變量和setter/getter啸罢。 但分類結構體中沒有屬性列表,所以不會自動生成 _成員變量 和 setter/getter胎食。 因此使用@property編譯和運行都不會報錯扰才,一旦使用 _成員變量 或 setter/getter,就會報錯厕怜。 可不可以手動實現(xiàn)setter/getter方法來避免崩潰衩匣? 答:可以的,OC是動態(tài)語言粥航,可以通過runtime添加 setter/getter方法琅捏。 objc_setAssociatedObject(),動態(tài)實現(xiàn)setter方法递雀,objc_getAssociatedObject()柄延,動態(tài)實現(xiàn)getter方法。
類擴展(Class Extension)
Extension 是 Category 的一個特例缀程。格式: @interface XXX () //私有屬性 //私有方法(如果不實現(xiàn)搜吧,編譯時會報警,Method definition for 'XXX' not found) @end
分類和類擴展的區(qū)別
1.Category原則上只能增加方法(可通過runtime解決增加屬性的問題); 2.Extention可增加方法和屬性杨凑,只是該屬性是@private類型滤奈,作用范圍是自身; 3.Category是運行時添加到類中蠢甲,Extension是編譯時添加到類中僵刮。
-
atomic 和 nonatomic
使用@property聲明屬性時据忘,會使用atomic/nonatomic關鍵字 atomic 和 nonatomic 區(qū)別在于系統(tǒng)自動生成setter/getter方法不一樣 atomic 系統(tǒng)自動生成的setter/getter方法會進行加鎖操作; nonatomic 系統(tǒng)自動生成的setter/getter方法不會進行加鎖操作搞糕。
atomic
系統(tǒng)生成的setter/getter方法進行加鎖操作勇吊,但這個鎖,僅僅保證了setter/getter存取方法的線程安全窍仰。 因加鎖的緣故汉规,其他線程要讀取這個屬性時,會先執(zhí)行完當前操作驹吮。 延伸問題: atmoic是線程安全嗎针史? 答:atomic只是對屬性的setter/getter方法進行加鎖操作,僅僅是set/get的讀取安全碟狞,并非真正的線程安全啄枕,線程安全還有讀取之外的其 他操作。 (比如:當一個線程正在setter/getter時族沃,有另一個線程 同時進行release操作频祝,這時可能導致crash)
nonatomic
系統(tǒng)生成的setter/getter方法沒有進行加鎖操作,讀取時不安全脆淹,但速度更快常空,當多個線程同時訪問同一屬性時,會出現(xiàn)無法預料的結果盖溺。
atomic和nonatomic的使用選擇
atomic能夠保證setter/getter操作的安全性漓糙,但是相對nonatomic更耗費資源,且速度更慢烘嘱,因此如果沒有多線程之間通信操作的情況下昆禽,使用nonatomic更好。
-
Objective-C是一門動態(tài)語言
動態(tài)拙友,不需要再編譯時確定所有的東西为狸,在運行時可以動態(tài)添加變量、屬性遗契、方法辐棒、類。Objective-C可以通過runtime牍蜂,在運行時動態(tài)的添加變量漾根、屬性、方法鲫竞、類辐怕,所以說Objective-C是一門動態(tài)語言。 動態(tài)性體現(xiàn): 1.動態(tài)類型从绘。如id類型寄疏。靜態(tài)類型因固定性和可預知性而使用廣泛是牢。靜態(tài)類型是強類型,而動態(tài)類型是弱類型陕截,運行時決定接收者驳棱; 2.動態(tài)綁定。讓代碼在運行時判斷需要調用的方法农曲,而不是在編譯時社搅。與其他面向對象語言一樣,方法調用和代碼并不是在編譯時連接在一起乳规,而是在消息發(fā)送時連接形葬,運行時決定調用哪個方法; 3.動態(tài)載入暮的。程序在運行時添加代碼模塊及資源笙以。用戶可根據(jù)需要加載可執(zhí)行代碼和資源,而不是啟動時家在所有組件青扔≡粗可執(zhí)行代碼中可以含有和程序運行時整合的新類翩伪。
-
weak微猖、strong、assign
由ARC引入 weak相當于OC中的assign缘屹,但是weak只能修飾OC對象凛剥,而assign可用于非OC對象,但是它們都不會造成引用計數(shù)+1轻姿; strong相當于OC中都retain犁珠,會造成引用計數(shù)+1。 ARC互亮,引用計數(shù)機制犁享,OC的內存管理機制。其原理:還要還有一個變量指向對象豹休,對象就會保持在內存中炊昆。 當指針指向新值,或者指針不存在時威根,相關聯(lián)的對象就會自動釋放凤巨。
strong
strong指針是強引用,能夠保持對象的生命洛搀,一個對象只要有strong指針指向它就不會被釋放敢茁; 相反,如果沒有一個strong指針指向它留美,那么它將自動釋放彰檬。 默認所有實例變量和局部變量都是strong指針伸刃。
weak
weak指針是弱指針,同樣可以指向一個對象逢倍,但是不是該對象的擁有者奕枝。即當對象銷毀時,weak指針自動指向nil(空指針)瓶堕。 這樣避免了指針繼續(xù)指向已釋放對象隘道,進而避免了野指針的出現(xiàn)。 延伸問題: IBOutlet連出來的視圖屬性為什么用weak修飾郎笆?那些控件對象不會自動釋放嗎谭梗? 如:@property (nonatomic, weak) IBOutlet UIButton *button; 答:xib創(chuàng)建或放置控件時,存在該引用關系: UIViewController->UIView->subviews->UIButton UIView持有了subviews(強引用)宛蚓,所以這里可以使用weak來修飾激捏。 為什么代理要用weak修飾? 答:防止循環(huán)引用凄吏。 如:控制器的view強引用這UITableView远舅,而tableview的delegate又是控制器。 如果不用weak痕钢,Controller->View->delegate-> Controller图柏,就造成了循環(huán)引用。
assign
assign主要用于修飾基本數(shù)據(jù)類型任连,如NSInteger蚤吹,CGFloat等,存儲在棧中随抠,內存不用程序員管理裁着。
待更...