Cocoa Foundation是iOS中的一個(gè)重要框架, 我們大量的使用了里面封裝好的接口. 但是還有許多我們需要的接口并不包含在Cocoa框架中, 比如RSA算法, MD5算法, SHA1算法, AES加密算法等, Cocoa對(duì)象庫(kù)里并沒(méi)有相應(yīng)的實(shí)現(xiàn). 這時(shí)候我們可以在Core Foundation框架里面去尋找. 包括NSString類里沒(méi)有的字符串編碼GBK, GB2312, GB18030等, 在Core Foundation里, 都能找到相應(yīng)的編碼. 建立Socket連接, 獲得輸入流和輸出流時(shí), 也需要使用Core Foundation里的CFNetwork Api等等.
Cocoa Foundation和Core Foundation的一個(gè)重要區(qū)別是: Cocoa Foundation是面向?qū)ο蟮? Core Foundation是非面向?qū)ο蟮? 這是造成內(nèi)存管理方式區(qū)別的原因. Cocoa Foundation中的對(duì)象使用ARC自動(dòng)管理內(nèi)存, 而對(duì)于Core Foundation中的對(duì)象則需要進(jìn)行手動(dòng)管理內(nèi)存, 使用完之后都需要手動(dòng)Release.
然后又涉及到另一個(gè)問(wèn)題, 就是Cocoa Foundation和Core Foundation相互轉(zhuǎn)換時(shí)內(nèi)存管理問(wèn)題. Cocoa Foundation和Core Foundation對(duì)象相互轉(zhuǎn)換時(shí)我們使用__bridge, __bridge_transfer, __bridge_retained
關(guān)鍵字.
- 1.
__bridge
: Cocoa Foundation和Core Foundation對(duì)象轉(zhuǎn)化時(shí)只涉及對(duì)象類型不涉及對(duì)象所有權(quán)的轉(zhuǎn)化; - 2.
__bridge_transfer
: Cocoa Foundation對(duì)象轉(zhuǎn)換成Core Foundation對(duì)象時(shí)酗宋,將Cocoa Foundation對(duì)象的所有權(quán)交給Core Foundation對(duì)象, 此時(shí)ARC就能自動(dòng)管理該內(nèi)存; - 3.
__bridge_retained
: (與__bridge_transfer
相反)常用在將Cocoa Foundation對(duì)象轉(zhuǎn)換成Core Foundation對(duì)象時(shí), 將Cocoa Foundation對(duì)象的所有權(quán)交給Core Foundation對(duì)象來(lái)管理;
當(dāng)使用_bridge_retained
標(biāo)識(shí)符以后, 代表Cocoa Foundation要將對(duì)象所有權(quán)交給Core Foundation對(duì)象自己來(lái)管理, 所以我們要在各種Ref使用完成以后用Release將其手動(dòng)釋放.
舉個(gè)栗子, FMDB中的一個(gè)大家都知道的一個(gè)方法:
- (void)inDatabase:(void (^)(FMDatabase *db))block {
/* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue
* and then check it against self to make sure we're not about to deadlock. */
FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock");
FMDBRetain(self);
dispatch_sync(_queue, ^() {
FMDatabase *db = [self database];
block(db);
if ([db hasOpenResultSets]) {
NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
#if defined(DEBUG) && DEBUG
NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]);
for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) {
FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue];
NSLog(@"query: '%@'", [rs query]);
}
#endif
}
});
FMDBRelease(self);
}
MDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
這句代碼中使用了__bridge
關(guān)鍵字. MDatabaseQueue
繼承自NSObject, NSObject是Cocoa的根類. 而dispatch_get_specific(const void *key);
則返回"the current subsystem-specific context"
, 因而__bridge
在代碼中的作用便是把Core Foundation對(duì)象轉(zhuǎn)換成Cocoa Foundation對(duì)象, 但是由于只涉及對(duì)象類型的轉(zhuǎn)換而沒(méi)有涉及對(duì)象控制權(quán)的轉(zhuǎn)換, 所有還需要手動(dòng)的進(jìn)行Retain和Release. 在代碼中體現(xiàn)為:
FMDBRetain(self);
FMDBRelease(self);
文章有參考網(wǎng)絡(luò)文章腺兴,如有錯(cuò)誤,歡迎討論指出务傲。