我是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方法。
答案 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
成员上调用方法。