2010-09-23 3 views
0

вот что я хочу:object-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];) от основного потока он запускает его на главном потоке, как я это знаю ?, хорошо, потому что method1 выполняет несколько операций, блоки пользовательский интерфейс. Что я сделал, чтобы перенаправить вызов таким образом:

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

это работает, но этот путь ограничивает меня, и у меня есть несколько вопросов к вам:

я понял, что, если я нахожусь в X-thread и вызов метода некоторого объекта, он будет выполнен в X-thread. Я думаю, что вызов метода будет добавлен (не уверен, что это слово) к runloop X-thread. правильно?

Есть ли способ установить это: любой вызов методов моего объекта будет выполняться в потоке объекта? (не делая все это).

также, это правильный способ для того, что я делаю? method1, method2 и т. Д. - это синхронизирующая версия моих функций. Так что они заблокируют пользовательский интерфейс. что «почему я предполагаю, что у другого потока есть путь.

спасибо за чтение !.

кстати. Я не использую GCD, так как мне нужно поддерживать iOS 3

+0

где определяется «runloopMethod»? Я хотел бы сделать то же самое, что вы делаете, но я немного смущен этой частью – abbood

ответ

0

Я предполагаю, что вы пытаетесь использовать потоки для выполнения фоновых задач, чтобы поддерживать пользовательский интерфейс. Это хорошо, но это будет очень сложный подход. Попробуйте вместо этого:

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, я хочу, чтобы пользовательский интерфейс был отзывчивым. Проблема с использованием detachNewThreadSelector или performSelectorInBackground заключается в том, что он не настраивает цикл запуска. – subzero

1

Объективный метод C код отправки среда выполнения не имеет механизма (AFAIK), чтобы определить неявно, следует ли выполнять вызов общего метода в другом потоке, чем текущий, поэтому вам придется реализовать свой собственный механизм явного фонового вызова, как и вы, используя функцию performSelector.

Если вы установили waitUntilDone на YES при вызове вашего фонового потока из основного потока, вы все равно заблокируете пользовательский интерфейс.

Если вы хотите, чтобы ваш метод1 выполнялся в фоновом режиме, а не блокировал пользовательский интерфейс, установите waitUntilDone в положение NO, и вам нужно выполнить фоновый поток, чтобы сообщить основной поток о завершении (или что-то еще) с помощью функции performSelectorOnMainThread.

Вы можете альтернативно иметь возможность использовать очереди операций для отправки сообщений в цикл выполнения фонового потока.

+0

hotpaw2, спасибо за ваш ответ. yesp, я понял о флагом YES/NO на performSelector ...., это была ошибка при отправке моего кода. я не знаком с очередями операций, до сих пор кажется, что это своего рода пул для одновременного запуска нескольких методов/операций, интересный момент: «Возможно, вы также сможете использовать очереди операций для отправки сообщений на ваш фоновый поток run loop. ", вы имели в виду, используя performSelector: onThread ...? – subzero