再来编辑:
要回答这个评论的问题:
什么IPC机制被用于在线程之间 通信息?共享 内存?套接字?马赫传讯?
NSThread在内部存储对主线程的引用,并通过该引用可以获得对该线程的NSRunloop的引用。内部的NSRunloop是一个链表,并且通过向runloop添加一个NSTimer对象,一个新的链表元素被创建并添加到列表中。所以你可以说它是共享内存,实际上属于主线程的链表,只是在不同的线程中修改。有互斥/锁(可能甚至NSLock对象),这将确保编辑链表是线程安全的。
伪代码:
// Main Thread
for (;;) {
lock(runloop->runloopLock);
task = NULL;
do {
task = getNextTask(runloop);
if (!task) {
// function below unlocks the lock and
// atomically sends thread to sleep.
// If thread is woken up again, it will
// get the lock again before continuing
// running. See "man pthread_cond_wait"
// as an example function that works
// this way
wait_for_notification(runloop->newTasks, runloop->runloopLock);
}
} while (!task);
unlock(runloop->runloopLock);
processTask(task);
}
// Other thread, perform selector on main thread
// selector is char *, containing the selector
// object is void *, reference to object
timer = createTimerInPast(selector, object);
runloop = getRunloopOfMainThread();
lock(runloop->runloopLock);
addTask(runloop, timer);
wake_all_sleeping(runloop->newTasks);
unlock(runloop->runloopLock);
当然,这过于简单,最细节的功能之间隐藏在这里。例如。如果定时器应该已经触发,getNextTask将只返回一个定时器。如果每个计时器的启动日期仍然在将来,并且没有其他事件要处理(如键盘,来自UI的鼠标事件或已发送的通知),则它将返回NULL。
我还不确定问题是什么。 A 选择器不过是一个包含被调用方法名称的C字符串。每个方法都是一个普通的C函数,并且存在一个字符串表,其中包含方法名称作为字符串和函数指针。这是Objective-C实际工作的基础。
正如我在下面写的,创建了一个NSTimer对象,它获取一个指向目标对象的指针和一个指向包含方法名称的C字符串的指针,并且当定时器触发时,它找到了使用字符串表(因此它需要方法的字符串名称)的目标对象(因此它需要对它的引用)。
不完全执行,但非常接近它:
可可每个线程都有一NSRunLoop(它总是在那里,你永远需要创建一个线程)。 PerformSelectorOnMainThread创建了一个NSTimer对象,如this,一个只触发一次,并且触发时间已经位于过去的位置(因此它需要立即触发),然后获取主线程的NSRunLoop并在那里添加定时器对象。一旦主线程空闲,它将搜索其Runloop中的下一个事件来处理(或者如果没有任何要处理的事情进入休眠状态,并且一旦添加事件就会再次被唤醒)并执行它。主线程在计划呼叫时很忙,在这种情况下,一旦它完成当前任务或当前处于睡眠状态,它将处理计时器事件,在这种情况下,它将通过添加事件而被唤醒并立即处理它。
一个很好的资料来看看苹果是如何最有可能做(没有人可以肯定,因为毕竟它的封闭源码)是GNUStep。由于GCC可以处理Objective-C(它不仅仅是Apple推出的扩展,即使是标准的GCC也可以处理它),但是,如果Obj-C没有苹果发布的所有基本类,那么GNU社区就会尝试重新使用它 - 实现你在Mac上使用的最常见的Obj-C类,它们的实现是OpenSource。
Here您可以下载最近的源码包。
解压缩并查看NSThread,NSObject和NSTimer的实现细节。我想苹果公司并没有这么做,我可以使用gdb来证明它,但是为什么他们会这样做呢?这是一个聪明的方法,效果非常好:)
如果你解释了为什么你认为你需要知道使用的确切机制,这可能是有用的。如果你想或者觉得你需要在应用程序代码中依赖它,那么很可能你错了...... – 2008-09-29 20:57:55
好点!在一个编辑中解释,希望能够让我更清楚地了解我所追求的。 – rpj 2008-09-29 21:31:21