Threading in Objective C
I am new to Objective-C and i was trying out a sample program in Threads from the book "Learn Objective-C for java developers". I am getting 6 errors on the function definition. Its with errors. Is there any link that gives good threading example for beginners like me.
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;
-(v开发者_运维百科oid)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
Could not find the setDoubleValue method in the class NSProgressIndicator.
Could not find the setDoubleValue method in the class NSProgressIndicator
For this one, that's because NSProgressIndicator is part of AppKit (the Cocoa GUI library), and you're only linking against Foundation (which is the non-GUI stuff). It seems in your code you've attempted to define an interface for NSProgressIndicator yourself, but you haven't declared any methods on it — that's why it's complaining about not being able to find the setDoubleValue method.
What should you do about it? Well, if you're wanting to use Cocoa's GUI stuff, you need to structure your program in the way Cocoa's GUI system expects. In Xcode, if you create a new Cocoa application it should give you a sample project to build on. In particular, your main()
function should contain return NSApplicationMain(argc, (const char **) argv);
, which handles starting a run loop to receive events.
If you just want to learn about threading, it may be better to abandon trying to get GUI stuff in the same program, and adapt your code to just print stuff to the console instead.
I find it hard to believe that this is an example from a book, since it seems fairly fundamentally broken!
Other errors I found when I tried running it:
Expected ')' before ':' token
This is on the line heartbeat->thread = [[NSThread alloc]initWithTarget:heartbeat selector:(heartbeatThread:) object:nil];
.
The problem there is the syntax for declaring a selector: instead of just saying selector:(heartbeatThread:)
, you need to say selector:@selector(heartbeatThread:)
.
'thread' undeclared (first use in this function'
In your header file, you claimed that the class Heartbeat
has a method called stop
. (That is, you defined -(void)stop;
in the @interface section for the Heartbeat class).
However, you implemented that method in the @implementation section for the Process
class.
You'd make it easier for yourself if you had one pair of .h and .m files per class, rather than trying to cram multiple class definitions into a single pair of files. That way you could make sure you were putting the implementation of the stop
method in the correct class's .m file.
property 'progress' requires method '-progress' to be defined - use @synthesize, @dynamic or provide a method implementation
In the implementation for process
you defined an @property called progress
. If you define a property, you either have to write getters and setters for it yourself, or write @synthesize progress
within your implementation. Doing the latter is equivalent to Objective-C generating your getters and setters automatically at runtime.
thread
is not a member of the Process
class; it belongs to the Heartbeat
class. You have to define a member in the Process
class to keep a reference on the Heartbeat
instance so you can call methods on its thread
member.
精彩评论