spandana spandana - 2 months ago 21
Objective-C Question

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;
-(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


Could not find the setDoubleValue method in the class NSProgressIndicator.

Answer

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.

Comments