iOS循環參考問題,ios循環參考
今天面試問道了循環參考,所以就看了看,原來只是知道使用了Block容易造成循環參考。今天就來簡單的介紹一些循環參考。
先來簡單介紹一下什麼是循環參考?
循環參考可以簡單的理解成:A對象引用了B對象,B對象又引用了A對象。兩者相互保持對方的一個引用。導致任何時候計數都不為0,最終兩者都無法釋放。
產生循環參考的方式:
1、NSTimer
比如說我在一個類中聲明了一個NSTimer計時器類。而在NSTimer 的方法
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
當我們在aSelector中調用了自己的屬性或者方法時(比如調用了自己的self.class),那麼當我們執行個體化這個類之後然後我們讓他延遲幾秒釋放,那麼我們會發現time中的aSelector會一直執行。現在就來簡單的分析一下吧:
timer沒有調用invalidate方法是不會因為類的釋放而停止的。而對於類執行個體來說:它認為timer沒有執行完畢,所以沒有機會進入dealloc。循環參考,相互等待。所以我們可以在類執行個體釋放之前手動調用一下NSTimer的invalidate方法。還有就是下面的代碼:
__weak ClassA *weakSelf = self;timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:weakSelf selector:@selector(startTimer) userInfo:nil repeats:YES];
所以我們在使用NSTimer時一定要注意NSTimer的invalidate時機。
2、Block
例如我們定義了一個block塊,然後作為了一個類的屬性變數,那麼當我們在這個塊中調用自己的屬性或者方法的時候就會產生循環參考。
解決循環參考方法:通過__weak聲明一個self的新變數來代替原來的self。這樣在塊中可以通過這個弱引用self來防止block中對self進行strong引用。
3、delegate
一般情況下我們聲明delegate時使用assign賦值,因為賦值屬性不會增加計數。
如果一個UITableViewController 對象a通過retain擷取了UITableView對象b的所有權,這個UITableView對象b的delegate又是a, 如果這個delegate是retain方式的,那基本上就沒有機會釋放這兩個對象了。
先簡單的介紹這麼多,因為這邊沒有電腦,也不太方便進行例子示範。有電腦了再補上去。這裡先做一下記錄。
------------------------------------------------------------------------------------結束------------------------------------------------------------------------------------
也很感謝哪位大神能夠附上一些例子。