iOS arc VS mrc學習筆記
一、* Core Foundation與objective-c Object進行交換 *
對於Core Foundation與objective-cObject進行交換時,需要用到的ARC管理機制有:
(1) (__bridge_transfer) op or alternatively CFBridgingRelease(op) is used to consume a retain-count of a CFTypeRef while transferring it over to ARC. This could also be represented by
id someObj =(__bridge <NSType>) op;
CFRelease(op);
(2) (__bridge_retained) op or alternatively CFBridgingRetain(op) is used to hand an NSObject over to CF-land while giving it a +1 retain count. You should handle a CFTypeRef you create this way the same as you would handle a result of CFStringCreateCopy().This could also be represented by
CFRetain((__bridge CFType)op);
CFTypeRef someTypeRef =(__bridge CFType)op;
(3) __bridge just casts between pointer-land and Objective-C object-land. If you have no inclination to use the conversions above, use this one.
二、* ARC和IOS4 *
ARC在IOS4是沒有 __weak 關鍵字的,需要使用 unsafe_unretained來代替。
三、* ARC中的記憶體洩露 *
使用了ARC也並不意味著我們的工程裡面不會出現記憶體洩露了。在ARC機制下,最常見導致記憶體洩露的是迴圈強引用。容易出現的場合有:
①Outlet型別指標
Outlet型別的指標變數應該用weak屬性來宣告
②委託
一定要將delegate的屬性設為weak,原因我就不解釋了,實在不明白,請猛擊這裡
③block
下面這段程式碼,在MRC條件下是沒有問題的:
MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
但是在ARC條件下,就會記憶體洩露,導致myController指向的物件無法釋放。
原因是,__block id x宣告的變數x用於block中時,MRC條件下是不會增加x的引用計數,但是在ARC條件下,會使x得引用計數加一,請各位務必注意!!!!!!!!!!!!
上述問題程式碼有以下幾種解決方案:
方案一:
MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil;
};
最簡單的解決辦法,在block中使用完myController時,是它指向nil,沒有strong型別的指標指向myController指向的物件時,該物件就回被釋放掉。
方案二:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler = ^(NSInteger result) {
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};
該方案使用了一個臨時的__weak型別的指標weakMyViewController,在block中使用該指標不會導致引用計數加一,但卻存在隱患,當該物件在外部被釋放時,block裡面執行的操作就無效了。下面的方案三可以解決這個問題。
方案三:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler = ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
// ...
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// ...
}
else {
// Probably nothing...
}
};
即在block中使用myController物件之前再宣告一個臨時的strong型別的指標,指向weak型別的指標,這時strongMyController指標就變成了有效的強引用,其指向的物件就能保證不被釋放掉。
④定時器
定時器也是非常容易產生記憶體洩露的地方。比如下面的程式碼
@implementation AnimatedView
{
NSTimer *timer;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{

 if ((self = [super initWithCoder:aDecoder])){
timer = [NSTimer scheduledTimerWithT imeInterval:0.1
target:self
selector:@selector(handleTimer:)
userInfo:nil
repeats:YES];
}
return self;
}
- (void)dealloc
{
[timer invalidate];
}
- (void)handleTimer:(NSTimer*)timer
{
//do something
}
乍一看這段程式碼沒啥問題,但是執行起來才發現dealloc方法是不會被呼叫的,self有一個timer的強引用,timer又有一個self的強引用,典型的迴圈引用!
解決方法是將timer的屬性設定為__weak。
四、* @autoreleasepool 和 NSAutoreleasePool *
ARC中是不支援使用NSAutoreleasePool的,但是可以使用@autoreleasepool代替。@autoreleasepool既可以用在ARC環境中,也可以用在非ARC環境中,而且效率要比前者高,蘋果官網中是這樣描述的:
ARC provides @autoreleasepool blocks instead. These have an advantage of being more efficient than NSAutoreleasePool.
五、* 使用ARC需要遵守的新規則 *
①不要在dealloc方法中呼叫[super dealloc];
②不能使用 retain/release/retainCount/autorelease
③不能使用 NSAllocateObject/NSDeallocateObject
④不能使用 NSZone
⑤Objective-C 物件不能作為C語言結構體(struct/union)的成員
參考連結:
相關文章
- iOS 記憶體管理MRCiOS記憶體
- ARC136F - PGF 學習筆記初步筆記
- Swift學習筆記(八)--析構器與ARCSwift筆記
- iOS Block學習筆記iOSBloC筆記
- iOS Runloop學習筆記iOSOOP筆記
- Vue學習筆記(二)------axios學習Vue筆記iOS
- Vue學習筆記 —— axiosVue筆記iOS
- Axios用法–學習筆記iOS筆記
- iOS runtime學習筆記iOS筆記
- iOS 屬性學習筆記iOS筆記
- iOS指標學習筆記iOS指標筆記
- 將 MRC 專案轉換為 ARC 專案
- iOS學習筆記02 UIScrollViewiOS筆記UIView
- iOS執行緒學習筆記iOS執行緒筆記
- iOS學習筆記-動畫篇1iOS筆記動畫
- iOS學習筆記43 Swift(三)類iOS筆記Swift
- iOS學習筆記05 觸控事件iOS筆記事件
- iOS arc 記憶體管理iOS記憶體
- IOS學習筆記——iOS元件之UIScrollView詳解iOS筆記元件UIView
- iOS學習筆記--PresentedVC自定義彈窗iOS筆記
- Xamarin 學習筆記 - 配置環境(Windows & iOS)筆記WindowsiOS
- iOS學習筆記04 檢視切換iOS筆記
- iOS學習筆記14 網路(三)WebViewiOS筆記WebView
- iOS學習筆記06 手勢識別iOS筆記
- iOS學習筆記47 Swift(七)泛型iOS筆記Swift泛型
- iOS學習筆記39 ReactiveCocoa入門iOS筆記React
- iOS學習筆記18 CoreData你懂的iOS筆記
- iOS-Socket開發學習筆記-1iOS筆記
- iOS學習筆記之 Objective-C (三)iOS筆記Object
- VMware和VS2010學習筆記筆記
- numpy的學習筆記\pandas學習筆記筆記
- iOS學習筆記——基礎控制元件(上)iOS筆記控制元件
- iOS學習筆記20 地圖(二)MapKit框架iOS筆記地圖APK框架
- iOS學習筆記01 APP啟動相關iOS筆記APP
- iOS學習筆記49 Swift(九)訪問控制iOS筆記Swift
- iOS學習筆記34 加速計和陀螺儀iOS筆記
- Objective C之NSDictionary學習筆記(IOS 9 1)Object筆記iOS
- iOS學習筆記-TableView效能優化篇1iOS筆記View優化