2010-09-23 31 views
0

這裏是我想要的:objective-c/iphone:如何設置某個對象的所有方法都會在特定的線程上運行?

在自己的線程中創建一個'生命'的對象,所有的方法都應該在該線程中執行。

即:

// i'm in the main thread 
MyClass *myObject = [ [MyClass alloc] init ]; // it creates its own thread 
[myObject method1]; // should execute the method1 in myObject's thread 
[myObject method2]; // should execute the method2 in myObject's thread 
[myobject release]; // should deallocate everything that is used for myObject and remove myObject's thread 

我一直在閱讀有關線程和runloops。我在init方法中創建了一個新線程,其入口點是runloop方法。 runloopMethod只是設置運行NSRunLoop所需的最基本的東西並運行它。

aThread = [[NSThread alloc] initWithTarget:self selector:@selector(runloopMethod) object:nil]; 
[aThread start]; 

它工作得很好,但是當我調用一個方法(即:[myObject method1];)從主線程運行時,它在主線程上,我怎麼知道呢?,好,因爲方法1執行多個操作,阻止UI。我所要做的就是將呼叫重定向這樣:

// on MyClass.m 
-(void) method1 { 
    if ([NSThread currentThread] != aThread) { 
     [self performSelector:@selector(method1) onThread:aThread withObject:nil waitUntilDone:YES]; 
    }else { 
     // do my stuff 
    } 

它的工作,但這種方式限制了我,我也有一些對你的問題:

我已經意識到,如果我在X線程和調用某個對象的方法,它將在X線程中執行。我認爲這個方法調用會被添加到X線程的runloop中(不知道它是否是這個詞)。對?

有沒有辦法來設置:任何對我的對象的方法的調用將在對象的線程上執行? (沒有做所有這些東西)。

另外,這是我正在做什麼的正確方法? method1,method2等是我的函數的同步版本..所以他們會阻止用戶界面。那'爲什麼我假設有另一個線程的方式。

感謝您的閱讀!

btw。我沒有使用GCD,因爲我需要支持iOS 3

+0

'runloopMethod'在哪裏定義?我想做同樣的事情,但是我對這部分感到困惑 – abbood 2012-09-12 06:59:19

回答

0

我猜你正在嘗試使用線程來運行後臺任務,以保持UI的響應。這很好,但這將是一個非常困難的方法。試試這個:

1)從主線程,火了一個新的線程:

[NSThread detachNewThreadSelector:@selector(methodThatTheThreadWillRun) 
         toTarget:nil 
         withObject:nil]; 

2)收件methodThatTheThreadShouldRun,做任何你需要做的事。它將在您剛剛創建的線程中執行。當它完成,有它的主線程上調用threadIsFinished

- (void)methodThatTheThreadWillRun { 
    MyClass *myObject = [ [MyClass alloc] init ]; 
    [myObject method1]; 
    [myObject method2]; 
    [myobject release]; 
    [self performSelectorOnMainThread:@selector(threadIsFinished)]; 
} 

3)最後,寫threadIsFinished

- (void)threadIsFinished { 
    // do whatever you need to do here: stop a spinner, etc. 
    // this will be invoked by the background thread but will 
    // execute on the main thread 
} 
+0

@yep Alexantd,我想保持UI的響應。關於使用detachNewThreadSelector或performSelectorInBackground的問題是它沒有配置運行循環。 – subzero 2010-09-27 22:07:33

1

的目標C方法調度運行時代碼沒有機構(AFAIK),以確定隱式地是否在與當前線程不同的線程上進行泛型方法調用,因此您必須像使用performSelector一樣實現您自己的顯式後臺調用機制。

如果您在從主線程調用後臺線程時將waitUntilDone設置爲YES,則仍會阻止UI。

如果您希望您的method1在後臺運行並且不阻止UI,請將waitUntilDone設置爲NO,並且必須後臺線程使用performSelectorOnMainThread通知主線程完成(或其他)。

您也可以使用操作隊列將消息發送到後臺線程的運行循環。

+0

hotpaw2,謝謝你的回答。 yesp,我意識到performSelector ....上的YES/NO標誌,發佈我的代碼時發生錯誤。我不熟悉操作隊列,到目前爲止,它似乎是一種可以同時觸發多個方法/操作的池,有趣的一點是:「您也可以使用操作隊列向您的消息發送消息後臺線程的運行循環。「,你的意思是,使用performSelector:onThread ...? – subzero 2010-09-29 18:37:39

相關問題