- delegate
- Associated Object
- Lock
- Toll-Free Bridging 和 Unmanaged
--
delegate
OC中使用delegate時候怀跛,我們用weak
修飾畴博。一是在這個delegate實際的對象被釋放時治唤,會被重置為nil娇钱。另一個是,能夠避免因為delegate不存在時候訪問導致的崩潰問題累榜。
swift中谴垫,由于protocol
可以被struct
enum
等非class
類型繼承蜡镶,如果設置delegate
時候使用weak
修飾。則該protocol
只能被class
繼承械巡,聲明的時候需要加上關鍵字@objc
刹淌,或者class
,指明這個協(xié)議只能被class
繼承讥耗。
@objc protocol MyProtocol {
func saySomething()
}
protocol MyProtocolNew : class {
func doSomething()
}
--
Associated Object
// 一: OC中通過runtime綁定類型給category添加屬性
@implementation Student (Category)
static char *mySchool = "mySchool";
- (void)setSchool:(NSString *)school {
objc_setAssociatedObject(self, mySchool, school, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)school {
return objc_getAssociatedObject(self, mySchool);
}
@end
// 二 : swift
import ObjectiveC.runtime
//Fish 類
class Fish: NSObject {
}
//添加屬性
var key : Void?
extension Fish {
var breed : String? {
set {
objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, &key) as! String?
}
}
}
--
Lock
多線程編程中芦鳍,為了安全的訪問同一個資源。OC中通常用@synchronized
修飾一個變量葛账。它實質(zhì)上是調(diào)用了objc_sync
中的objc_sync_enter
和objc_sync_exit
方法柠衅,并且加入了一些異常判斷。所以雖然swift中已經(jīng)沒有了@synchronized
籍琳,我們可以直接調(diào)用方法objc_sync_enter & objc_sync_exit
菲宴。
let obj = String()
objc_sync_enter(obj)
//do something
objc_sync_exit(obj)
//可以自己寫個全局的方法,就能直接像OC一樣調(diào)用方法了
func synchronized(_ lock: AnyObject, closure: () -> ()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
--
Toll-Free Bridging 和 Unmanaged
swift對Core Foundation
框架的內(nèi)存管理進行了一些列的簡化趋急,降低了使用CF框架的難度喝峦。
-
對Cocoa中的Toll-Free Foundation的處理。Cocoa中大部分
NS
開頭的類在CF
中都有對應的存在呜达。在OC中ARC負責的只是NSObject的自動引用計數(shù)谣蠢,因此對于CF對象無法進行內(nèi)存管理。把對象在NS和CF之間轉(zhuǎn)換的時候查近,需要向編譯器說明是否轉(zhuǎn)移內(nèi)存的管理權眉踱。對于不涉及內(nèi)存管理的轉(zhuǎn)換情況,在轉(zhuǎn)換的時候加上__bridge
說明霜威,表示內(nèi)存管理權不變谈喳。NSURL *fileURL = [NSURL URLWithString:@"SomeURL"]; SystemSoundID theSoundID; OSStatus error = AudioServicesCreateSystemSoundID( (__bridge CFURLRef)fileURL, &theSoundID);
swfit中,這樣的轉(zhuǎn)換戈泼,可以省略__bridge
import AudioToolbox
let fileURL = NSURL(string: "SomeURL")
var theSoundID: SystemSoundID = 0
AudioServicesCreateSystemSoundID(fileURL!, &theSoundID)
- OC中婿禽,不能處理CF類型的創(chuàng)建和釋放。對于CF的API大猛,如果名字中含有
Create
Copy
Retain
扭倾,使用完成后,需要我們調(diào)用CFRealease
是釋放挽绩。但是在Swift中膛壹,不用顯式的釋放帶有這些關鍵字的內(nèi)容了。就是說Swift時代琼牧,CF也納入了ARC的管理陣營恢筝。原理就是在合適的地方哀卫,系統(tǒng)自己給加上了CF_RETURNS_RETAINED
和CF_RETURNS_NOT_RETAINED
這樣的標注。
但是有?點例外撬槽,那就是對于?系統(tǒng)的 CF API (?如你??寫的或者是第三?的)此改,因為并沒有強制機制要求它們?定遵照 Cocoa 的命名規(guī)范,所以貿(mào)然進??動內(nèi)存管理是不可?的侄柔。如果你沒有明確地使?上?的標注來指明內(nèi)存管理的?式的話共啃,將這些返回 CF 對象的 API 導? Swift 時,它們的類型會被對對應為 Unmanaged<T> 暂题。