Objective-C线程

时间:2013-04-08 18:41:12

标签: objective-c multithreading

我想在objective-c中学习更多关于线程的知识,所以我做了一个小测试程序,它只是循环并输出它所在循环的迭代。 但是,我得到的输出并不是我所期待的。我知道为什么,但首先是我的代码:

的main.m

#import <Foundation/Foundation.h>
#import "Car.h"


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Car* myCar = [[Car new] autorelease];

        [myCar performSelectorInBackground:@selector(LoopAndSay) withObject:nil];

        for(int i = 0; i < 100; i++ )
        {

            NSLog(@"Main loop on %i", i);
        }


    }
return 0;
}

Car.m

#import "Car.h"

@implementation Car
@synthesize name, model;

-(void) LoopAndSay {

    for(int i = 0; i < 100; i++)
    {
        NSLog(@"Looping for the %i time", i);

    }

}
@end

现在,如果我按原样运行它,背景循环有时不会完成(在迭代94和97之间停止)。另外,如果我切换我的代码,以便直到主线程循环之后才调用后台循环,那么它将不会运行任何迭代。 这是因为主线程已完成并且不想等待后台线程运行完成?如果是这种情况,有没有办法强制程序继续运行,直到主线程和任何后台线程都完成为止?

2 个答案:

答案 0 :(得分:3)

这几乎可以肯定是因为在线程完成之前退出自动释放池的范围你的main函数在后台线程完成之前返回。尝试在结束前添加sleep(3)或其他内容,看看后台线程是否完成。

在Mac OS X上,进程在其所有“前台”线程完成后终止。 peformSelectorInBackground:只创建一个后台线程,所以一旦main返回,你就没有前台线程了,你的进程就被终止了。

答案 1 :(得分:3)

这是因为使用performSelectorInBackground:...和其他Objective-C API创建的所有线程都是分离的,因此程序可以终止而无需等待它们完成。来自Threading Programming Guide

  

在应用程序退出时,分离的线程可以立即终止,但是可连接的线程不能。 [...]如果你想创建可连接的线程,唯一的方法是使用POSIX线程...

在这种情况下,您的主线程循环恰好比后台线程更快完成,因此后台线程循环不会一直运行到最后。您也可以使用NSOperationQueue代替使用POSIX线程(这样不太方便),它可以让您轻松等待队列中的所有操作完成。