NSTimer销毁及失效的常用解决办法联合runloop
a.NSTimer销毁的一种简单方法,在viewWillDisappear or viewDidDisappear 设置[_timer invalidate] _timer = nil 即刻可;
1.第一个界面点击跳转
2.第二个界面设置定时器以及在-(void)viewWillDisappear:(BOOL)animated{}中或者-(void)viewDidDisappear:(BOOL)animated{} 进行销毁;
3.第一次跳转的时候打印信息
4.第二次跳转打印信息,打印信息(并不是从0开始,而是接在之前)
5.NSTimer强引用图解:
控制器强引用定时器;定时器里面的target为self对控制器又造成强引用,互相强引用,造成循环引用,无法释放,dealloc无法执行
b.runloop;
1.autorelease里面的对象什么时候被释放?
答:对于每 个Runloop, 系统会隐式创建 个Autorelease pool,这样所有的release pool会构成1个象CallStack样的个栈式结构,在每 个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool的每个Object会被release。那什么是 个Runloop呢? 个UI事件,Timer call,delegate call, 都会是 个新的Runloop(个事件处理)。
2.Run loop,
在iOS开发中,每一个线程都有一个RunLoop,主线程的RunLoop默认是开启的RunLoop就是一个被优化后的死循环,当没有操作会进入休眠,当有事件传入时会被启动;正如其名,loop表某种循环,和run放在一起就表1直在运 行着的循环。实际上,run loop和线程是紧密相连的,可以这样说run loop是为了线程 ,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分,Cocoa和CoreFundation都提供了run loop对象 便配置和管理线程的run loop(以下都已Cocoa为例)。每个线程,包括程序的主线程(main thread)都有与之相应的run loop对象。
注:( 1个 法就可以看做 个事件处理)
3.主线程的run loop默认是启动的。iOS的应 程序 ,程序启动后会有 个如下的main()函数:
重点是UIApplicationMain()函数,这个 法会为mainthread设置 个NSRunLoop对象,这就解释了本 开始说的为什么我们的应可以在操作的时候休息,需要让它干活的时候 能 响应。
4.对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以 动配置和启动,如果线程只是去执 个 时间的已确定的任务则不需要。
5.在任何 个Cocoa程序的线程中,都可以通过:NSRunLoop*runloop =[NSRunLoop currentRunLoop];来获取到当前线程的run loop。
6.Cocoa中的NSRunLoop类并不是线程安全的我们不能再 个线程中去操作另外 个线程的run loop对象,那很可能会造成意想不到的后果。不过幸运的是CoreFundation中的不透明类CFRunLoopRef是线程安全的, 且两种类型 的run loop完全可以混合使 。Cocoa中的NSRunLoop类可以通过实例 法:
- (CFRunLoopRef)getCFRunLoop;获取对应的CFRunLoopRef类,来达到线程安全的 的。
7.Run loop的管理并不完全是自动的。我们仍必须设计线程代码以在适当的时候启动run loop并正确响应输事件,当然前提是线程中需要到runloop。 且,我们还需要使while/for语句来驱动runloop能够循环运 ,下 的代码就成功驱动了个runloop:
8.Run loop同时也负责autorelease pool的创建和释放,MRC会经常到很多动释放的对象,如果这些对象不能够被即时释放掉,会造成内存占量急剧增 。Run loop就为我们做了这样的作,每当个运循环结束的时候,它都会释放 1次autorelease pool,同时pool中的所有类型变量都会被释放掉。
9.Run loop的优点;1个run loop就是 个事件处理循环, 来不停的监听和处理输事件并将其分配到对应的目标上进处理。
runloop 常用地方:
aa . 利用RunLoop解决NSTime不执行的问题
ab. 利用线程的方式解决NSTime不执行的问题 [[NSRunLoop currentRunLoop] run];
ac.解决滑动scrollview时 NSURLConnection代理不执行的情况