-(voID)uploadPhotos{ NSautoreleasePool* pool = [[NSautoreleasePool alloc] init]; NSTimer* timer = [NSTimer timerWithTimeInterval:60 target:self selector:@selector(tryToUploadPhotos) userInfo:nil repeats:YES]; NSRunLooP* runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSRunLoopCommonModes]; [runLoop run]; [pool release];}
这一小段代码是用来定时上传照片的,我们只讨论代码本身,不去管计划任务的必要性。
作为一个iOS新手,可以问这么几个问题
autorelease pool
Cocoa的内存管理主要依赖于Reference Counting,而NSautoReleasePool就是用来支持它的. autorelease pool中存放的对象会在其自身干枯(drain)时被release.
一般来说在应用的main thread中,已经存在了一个autorelease pool. 有两种情况需要开发者自己新建autorelease pool:
在main thread中,在某个方法中出现大量的autoreleased objects,为了避免memory footprint的增大,可以手动创建一些autorelease pool用来drain objects.
创建新的thread,并在其中访问了Cocoa,需要在访问的前创建autorelease pool,访问结束后drain.
最后一点,在每个thread中都会维持一个stack,其中放置着所有在这个thread中创建但未销毁的pool,每当一个新的pool创建后,它就位于stack的最顶端,相应autoreleased object就会放入其中. 当pool drain的时候,它就会从stack的顶端移除,并且release掉其包含的objects.
NSautoreleasePool可以同时有多个,它的组织是个栈,总是存在一个栈顶pool,也就是当前pool,每创建一个pool,就往栈里压一个,改变当前pool为新建的pool,然后,每次给pool发送drain消息,就d出栈顶的pool,改当前pool为栈里的下一个pool。
接下来要注意,对象,并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。
当当前pool接受到drain消息时,它就简单的对它所管理的所有对象发送release消息。
到了这里,一定会发现这个所谓的pool有个坑人的特性,即,如果pool中被管理的对象接受到pool发送的那个release消息后,它的引用计数大于0,那么pool虽然消失了,但是那个对象还是存在的!
run loop
Run loop(CFRunLoop)是一个事件处理循环,你可以用来安排工作并协调你所收到的事件。使用run loop的目的是保持你的thread当有事件处理时处于忙状态并当没有事件处理时进入休眠。
Run loop是一组架构用来管理thread中收到的异步消息。Run loop运行时对thread中的一个或多个事件源进行监控。当事件到达时,系统将thread唤醒并将事件发送给run loop,然后run loop将事件再次转发给你所指定的处理函数。如果没有收到事件或事件处理完成后,run loop将thread设置为休眠。你可以不为你所创建的thread设置run loop,但设置了将为用户提供很好的体验。Run loop为创建长时间运行且消耗少量资源的thread提供了可能。因为run loop将其所属thread设置为休眠状态如果没有事件收到。要对run loop进行配置,你所要做的是创建你的thread,获得对run loop对象的引用,安装你的事件处理器并运行run loop。Cocoa为你在main thread中自动配置了run loop,如果你要创建另一个长时间运行的thread,则你必须自己对run loop进行配置。
Run loop就像它的名字一样,是你thread中的一个循环并对收到的事件进行处理。你的代码提供控制语句用来对run loop进行执行——换句话说:你的代码提供while或for循环来驱动run loop。在你的循环中,你使用run loop对象来“运行”事件处理代码。事件处理代码主要进行接收事件并调用事件处理函数。
Run loop从两个不同的事件源中接收消息。input sources(CFRunLoopSource)投递异步消息,通常来自于另一个thread或另一个应用程序。Timer sources(CFRunLoopTimer)当在计划的时间或重复的时间间隔内投递同步消息。两种事件源都使用应用程序指定的处理方式对到达的事件进行处理。下图展示了run loop和不同的事件源结构。
input sources投递异步消息至对应的处理器并导致退出runUnitDate:方法(该方法在将run loop与thread关联时调用)的执行。Timer sources投递同步消息至对应的处理器但并不导致run loop退出。为了能对input sources进行额外处理,run loops也能根据run loop的行为产生相应的通知。注册run loop observers(CFRunLoopObserver)可以接收到这些通知并使用它们在thread上进行额外的处理。
你的应用程序不需要创建或显式地管理NSRunLoop对象。每一
个NSThread对象,包括应用程序的main Thread都会自动创建一个NSRunLoop对象。如果你需要访问当前thread的run loop,你可以使用NSRunLoop对象的类方法currentRunLoop。
Timer(定时器)也是通过run loop进行处理。与run loop进行比较,你通常在你的程序中直接使用Timer。
创建一个timer的最简单方法:
[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];
有些情况下你也可能创建自己的NSTimer对象,从而可以自己对Timer进行释放和重用。
总结以上是内存溢出为你收集整理的从定时任务看NSRunLoop和Autorelease全部内容,希望文章能够帮你解决从定时任务看NSRunLoop和Autorelease所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)