__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];