惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy International News Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Tenable Blog
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
The Hacker News
The Hacker News
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
P
Proofpoint News Feed
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
L
LangChain Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东

博客园 - Orca

IOS程序崩溃报告管理解决方案(Crashlytics 在2014-09-24) 商业模式到底是什么?(转载) 实现不同行业不同职位的体验 OpenGL中主要的4种矩阵如何理解(使用类比方式以便于方便理解) OpenGL ES入门指南-原理(转载) NSTimer与Run loop Modes(转载) 多线程:NSThread和runloop(转载) iOS内存暴增问题追查与使用陷阱 (转载) 需要时显示——论App中的功能可见性(转) 如果爱,请深爱:10大iOS开发者最喜爱的类库(转载) 完整地翻译了一份ASIHttpRequest的文档 (转载) IOS 多线程编程指南【中文完整翻译版】(转载) IOS 5 Storyboard全解析-第二部分(转载) IOS 5 Storyboard全解析-第一部分(转载) IOS 学习总结(不断更新中) IOS 5 中@synthesize window = _window是什么意思呢 IOS 5 中为什么outlet 输出口总是设定成弱类型(weak)呢 浅谈iOS MVC 学习基础(转) iOS里的MVC(转)
从定时任务看NSRunLoop和Autorelease(转载)
Orca · 2012-12-04 · via 博客园 - Orca
-(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新手,可以问这么几个问题

  1. NSAutorelesePool 是用来干嘛的?这里为什么要用?
  2. NSRunLoop是什么?有什么用?

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消息,就弹出栈顶的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进行释放和重用。