目标C中的线程化

时间:2011-05-23 09:29:49

标签: objective-c

我是Objective-C的新手,我正在从“为Java开发人员学习Objective-C”一书中尝试Threads中的示例程序。 我在函数定义上遇到6个错误。 它有错误。 是否有任何链接可以为像我这样的初学者提供良好的线程示例。

Thread2.m

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

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Process* process = [Process new];
    NSProgressIndicator* indicator = [NSProgressIndicator new];
    Heartbeat* heartbeat = [Heartbeat startHeartbeatProcess:process withIndicator:indicator];
    [heartbeat stop];
    [pool drain];
    return 0;
}

Process.h

#import <Foundation/Foundation.h>

@interface Process : NSObject {

}
@property double progress;
@end

@interface NSProgressIndicator : NSObject {

}

@end


@interface Heartbeat : NSObject {

    @public
    NSThread* thread;
    NSProgressIndicator* indicator;
    Process* monitor;
}

+(Heartbeat*)startHeartbeatProcess:(id)process withIndicator:(NSProgressIndicator*)progress;
-(void)stop;
-(void)heartbeatThread:(id)ignored;
-(void)updateIndicator;

@end

Process.m

#import "Process.h"

@implementation Process

+(Heartbeat*)startHeartbeatProcess:(id)process withIndicator:(NSProgressIndicator*)progress {

    Heartbeat* heartbeat = [Heartbeat new];
    heartbeat->monitor = process;
    heartbeat->indicator = progress;
    heartbeat->thread = [[NSThread alloc]initWithTarget:heartbeat selector:(heartbeatThread:) object:nil]; //'heartbeatThread' undeclared
    [heartbeat->thread start];

    return heartbeat;
}

-(void)stop {

    [thread cancel]; //thread undeclared
}

-(void)heartbeatThread:(id)ignored {

    while (![thread isCancelled]) { 
        //thread undeclared
        [self performSelectorOnMainThread:@selector(updateIndicator) withObject:nil waitUntilDone:YES];
        [NSThread sleepForTimeInterval:0.5];
    }
}

-(void)updateIndicator {

    [indicator setDoubleValue:monitor.progress];
}
@end

在NSProgressIndicator类中找不到setDoubleValue方法。

2 个答案:

答案 0 :(得分:2)

  

无法在NSProgressIndicator类中找到setDoubleValue方法

对于这个,那是因为NSProgressIndicator是AppKit(Cocoa GUI库)的一部分,而你只是链接到Foundation(这是非GUI的东西)。在您的代码中,您似乎试图自己为NSProgressIndicator定义一个接口,但是您没有在其上声明任何方法 - 这就是为什么它抱怨无法找到setDoubleValue方法。

你应该怎么做?好吧,如果你想使用Cocoa的GUI东西,你需要以Cocoa的GUI系统所期望的方式构建你的程序。在Xcode中,如果您创建一个新的Cocoa应用程序,它应该为您提供一个示例项目来构建。特别是,您的main()函数应包含return NSApplicationMain(argc, (const char **) argv);,它处理启动运行循环以接收事件。

如果您只是想了解线程,最好放弃尝试在同一个程序中获取GUI内容,并调整代码,只需将内容打印到控制台即可。

我觉得很难相信这是一本书中的一个例子,因为它似乎已经从根本上被打破了!

我尝试运行时发现的其他错误:

  

预期')'之前':'代币

这是heartbeat->thread = [[NSThread alloc]initWithTarget:heartbeat selector:(heartbeatThread:) object:nil];行。

问题在于声明选择器的语法:您需要说selector:(heartbeatThread:)而不是只说selector:@selector(heartbeatThread:)

  

'thread'未声明(首次使用此函数'

在您的标头文件中,您声称类Heartbeat有一个名为stop的方法。 (也就是说,您在Heartbeat类的@interface部分中定义了-(void)stop;。)

但是,您在Process类的@implementation部分中实现了该方法。

如果每个类都有一对.h和.m文件,而不是尝试将多个类定义塞入一对文件中,那么你会更容易。这样你就可以确保将stop方法的实现放在正确的类的.m文件中。

  

属性'进度'需要定义方法'-progress' - 使用@synthesize,@ dynamic或提供方法实现

process的实现中,您定义了一个名为progress的@property。如果定义属性,则必须自己编写getter和setter,或者在实现中编写@synthesize progress。执行后者相当于Objective-C在运行时自动生成getter和setter。

答案 1 :(得分:1)

thread不是Process类的成员;它属于Heartbeat类。您必须在Process类中定义一个成员以保留对Heartbeat实例的引用,以便您可以在其thread成员上调用方法。