Я новичок в Objective-C.В настоящее время я работаю с потоками.
Я должен сделать синхронное выполнение потоков.Я использую NSInvocationOperaion
для создания потока.
У меня есть два потока.Мне нужно дождаться 1-го потока, чтобы сообщить о событии или тайм-аут.Сообщение о событии может быть сделано с помощью NSConditionLock
.Как сигнализировать тайм-аут.Я не мог использовать waitUntilDate
метод здесь, поскольку время ожидания не является фиксированным значением.Есть ли способ сделать это?
EDITED
main.m
------
#import "PseudoSerialQueue.h"
#import "PseudoTask.h"
int main()
{
PseudoSerialQueue* q = [[[PseudoSerialQueue alloc] init] autorelease];
[q addTask:self selector:@selector(test0)];
[q addTask:self selector:@selector(test1)];
[q addTask:self selector:@selector(test2)];
[q quit];
return 0;
}
PseudoTask.h
-----------------
#import <Foundation/Foundation.h>
@interface PseudoTask : NSObject {
id target_;
SEL selector_;
id queue_;
}
@property(nonatomic,readonly)id target;
-(id)initWithTarget:(id)target selector:(SEL)selector queue:(id)queue;
-(void)exec;
@end
PseudoTask.m
-----------------
#import "PseudoTask.h"
@implementation PseudoTask
@synthesize target = target_;
-(id)initWithTarget:(id)target selector:(SEL)selector queue:(id)queue
{
self = [super init];
if (self) {
target_ = [target retain];
selector_ = selector;
queue_ = [queue retain];
}
return self;
}
-(void)exec
{
[target_ performSelector:selector_];
}
-(void)dealloc
{
[super dealloc];
[target_ release];
[queue_ release];
}
@end
PseudoSerialQueue.h
----------------------------
#import <Foundation/Foundation.h>
#import "PseudoTask.h"
@interface PseudoSerialQueue : NSObject {
NSCondition* condition_;
NSMutableArray* array_;
NSThread* thread_;
}
-(void)addTask:(id)target selector:(SEL)selector;
@end
PseudoSerialQueue.m
----------------------------
#import "PseudoSerialQueue.h"
@implementation PseudoSerialQueue
-(id)init
{
self = [super init];
if (self) {
array_ = [[NSMutableArray alloc]init];
condition_ = [[NSCondition alloc]init];
thread_ = [[NSThread alloc] initWithTarget:self selector:@selector(execQueue) object:nil];
[thread_ start];
}
return self;
}
-(void)addTask:(id)target selector:(SEL)selector
{
[condition_ lock];
PseudoTask* task = [[PseudoTask alloc] initWithTarget:target selector:selector queue:self];
[array_ addObject:task];
[condition_ signal];
[condition_ unlock];
}
-(void)quit
{
[self addTask:nil selector:nil];
}
-(void)execQueue
{
for(;;)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init];
[condition_ lock];
if (array_.count == 0) {
[condition_ wait];
}
PseudoTask* task = [array_ objectAtIndex:0];
[array_ removeObjectAtIndex:0];
[condition_ unlock];
if (!task.target) {
[pool drain];
break;
}
[task exec];
[task release];
[pool drain];
}
}
-(void)dealloc
{
[array_ release];
[condition_ release];
[super dealloc];
}
@end
Я не мог передать себя из main.Надеюсь, я по ошибке называю это.Ошибка: 'self' undeclared идет.
Я не мог понять - (void) exec {[target_ executeSelector: selector_];} в PseudoTask.m
target_ это не метод, а его ивар.Я не получаю никаких ошибок или предупреждений. Но я не мог понять этот код.
Я пишу то, что понял из вашей программы. Пожалуйста, исправьте меня, если я неправильно понимаю программу.
Поток execQueue создается при инициализации PseudoSerialQueue и ожидает сигнала от метода addTask.Метод addTask вызывается в методе quit, и переданные параметры равны nil. Я не мог понять, почему следует передавать параметр nil.
Было бы полезно, если вы объясните это. Спасибо.