筆者在閱讀中總結了一下,在iOS平台容易引起循環參考的幾個情境:
一、parent-child相互持有、委託模式
二、block
三、NSTimer
四,比如把self假如array中。也會造成循環參考
五,使用類別添加屬性 一、parent-child相互持有、委託模式
【案例】:
@interface FTAppCenterMainViewController (){}@property(weak,nonatomic) UITableView* myTableView;@end
這裡面的myTableView就使用了weak修飾符。
@property (nonatomic, weak) id<FTActionSheetDelegate>delegate;
【推薦方法】:
child只有parent的對象為weak類型:
@property (nonatomic, weak) id<FTActionSheetDelegate>delegate;
二、block
【案例】:
看下面的代碼:
typedef void (^RequestNaviCallBack)(NSInteger naviCode,NSInteger httpCode,NSError * error);@interface FtNaviManager : NSObject{}@property (nonatomic, strong) RequestNaviCallBack naviCallBack;
這是一個請求導航的類,類屬性持有了RequestNaviCallBack,這時,如果RequestNaviCallBack再持有self, 必然造成循環參考。
當然還有一些隱式(間接)循環參考。ObjectA 持有ObjectB,ObjectB持有block。那麼在block中調用ObjectA的self會造成間接循環參考。
【推薦方法】:
如果有顯示循環參考,編譯器會提示警告,在block引用self的時候最好使用weak-strong dance技術。
weak-strong dance技術
詳細的weak-stong-dance技術,查看這裡 三、NSTimer
【案例】:
@interface FtKeepAlive : NSObject{ NSTimer* _keepAliveTimer; // 發送心跳timer}//實現檔案_keepAliveTimer = [NSTimer scheduledTimerWithTimeInterval:_expired target:self selector:@selector(keepLiveStart) userInfo:nil repeats:YES];
類持有了_keepAliveTimer,_keepAliveTimer又持有了self,造成循環參考。
【推薦方法】:
NSTimer會持有對象,所以:在刪除對象之前,需要將timer的invalidate方法。
-(void)stopKeepAlive{ [_keepAliveTimer invalidate]; _keepAliveTimer = nil;}
四,比如把self加入array中。也會造成循環參考
五,使用類別添加屬性
比如:有一個類A,給A動態添加屬性p。如果p中再引用類A,容易造成循環參考