__block
與__weak
的區別:__block int num = 10; // __block能夠修飾對象與基本數據類型 // __weak int num = 10; // __weak只能修飾對象,不能修飾基本數據類型 self.block = ^{ num++; NSLog(@"內部值:%d", num); }; self.block(); NSLog(@"外部值:%d", num);
使用__block
修飾基本數據類型:當沒有使用__block
修飾變量num時,此時的num變量在block內可讀不可寫,由於此時block內部會將變量作處理,從新生成一個變量指向num,使得在block內外操做的其實不是相同的num變量。當使用了__block
修飾變量以後,block內部使用此變量時,不會再生成新的變量,因此此時外部對變量num的操做也會改變block內num變量的值。異步
使用__weak避免循環引用:
使用block時,爲了不循環引用,通常用__weak
定義一個弱引用weakSelf
,因爲弱引用不持有對象實例,當對象不被使用時,weakSelf將會釋放並被系統所回收,使得block再也不強引用着self不釋放,避免出現循環引用。oop
總結性能
__block
能夠修飾對象和基本數據類型;在MRC和ARC下均可以使用,缺點在於在ARC下,會引發循環引用。
__weak
只能修飾對象,不能修飾基本數據類型;不會發生循環引用。
__weak
直接修飾生成對象會被釋放,__block
則不會code
block
循環引用在堆上的對象與堆上的對象互相引用形成的環,就會引發循環引用對象
對象被強引用(strong)後,就不會被釋放,除非強引用者被釋放。
循環引用就是,對象間相互強引用了對方,而致使雙方都沒法被釋放。生命週期
循環引用帶來的危害內存
**爲了不循環引用,同時爲了防止異步的block在回調的時,block執行的過程當中被意外釋放,咱們使用__strong 對block外的__weak對象再次強引用,既可以防止引用循環,又可以保證代碼的正確執行。**get
dealloc
方法在對象被釋放或者說一個對象或者類被置爲nil的時候,執行dealloc
方法it
正常狀況下,每個OC對象最後應該都會調用dealloc方法,表示結束了生命週期,在內存中銷燬。變量
什麼狀況下,會不調用dealloc
方法?
delegate
應該使用weak修飾,不然會引發循環引用NSTimer
與RunLoop
NSTimer
開啓時,有時候會有延時(不會當即執行)。由於若是RunLoop
正在執行一個持續性的運算,timer就會被延時觸發。
UIScrollView
上的定時器,在scrollView滑動的時候,定時器方法沒有被調用,須要添加到RunLoopMode
NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Handlete) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];