首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSCondition ->Objective C

NSCondition ->Objective C
EN

Stack Overflow用户
提问于 2011-06-06 19:15:59
回答 2查看 5.1K关注 0票数 3

我是Objective-C的新手。我目前正在处理线程。

我必须同步执行线程。我正在使用NSInvocationOperaion生成一个线程。

我有两个线程。我需要等待第一个线程发出事件或超时的信号。发信号通知事件可以由NSConditionLock完成。如何发出超时信号。我不能在这里使用waitUntilDate方法,因为超时不是一个固定值。有没有办法做到这一点?

编辑过的

代码语言:javascript
复制
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.Hope传递self,我把它叫错了。错误:未声明的‘self’即将到来。

我无法理解伪任务中的-(空)exec{ target_ performSelector:selector_;}。

target_不是一个方法,它是一个ivar。我没有得到任何错误或warning.But我不能理解该代码。

我正在写我从你的program.Please中理解的东西,如果我对程序的理解是错误的,请纠正我。

当PseudoSerialQueue被初始化并等待来自addTask方法的信号时,就会产生线程execQueue。quit方法中调用了addTask方法,并且传递的参数为nil。我无法理解为什么要传递nil参数。

如果你解释一下it.Thanks,那会很有帮助的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-06 19:52:01

你是说NSCondition?您可以使用waitUntilDate:作为相对时间。

代码语言:javascript
复制
[condition lock];
// wait 5 seconds. 
[condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
[condition unlock];

编辑:

我的PseudoSerialQueue类需要从从NSObject派生的类中调用,如下所示。

代码语言:javascript
复制
@interface Test : NSObject
@end

@implementation Test
- (void)test0
{
}

- (void)test1
{
}

- (id)init
{
    self = [super init];
    return self;
}

- (void)exec
{
    PseudoSerialQueue *q = [[PseudoSerialQueue alloc] init];
    [q addTask:self selector:@selector(test0)];
    [q addTask:self selector:@selector(test1)];
    [q addTask:self selector:@selector(test0)];
    [q quit];
}
@end

你可以从main函数调用它。

代码语言:javascript
复制
Test *test = [[Test alloc] init];
[test exec];

我不明白为什么要传递一个nil参数。

我只是选择它作为退出PseudoSerialQueue中循环的消息。

票数 2
EN

Stack Overflow用户

发布于 2011-06-06 19:34:54

在这两种情况下,让第一个线程向第二个线程发送信号;然后在第二个线程中,您可以根据第一个控制器中的某个只读标志或您的模型(比如isDataAvailable)中的某个只读标志来判断是哪种情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6251202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档