views:

370

answers:

1

Hi there,

I have a program that needs to use sleep. Like really needs to. In lieu of spending ages explaining why, suffice to say that it needs it.

Now I'm told to split off my code into a separate thread if it requires sleep so I don't lose interface responsiveness, so I've started learning how to use NSThread. I've created a brand new program that is conceptual so to solve the issue for this example will help me in my real program.

Short story is I have a class, it has instance variables and I need a loop with a sleep to be depended on the value of that instance variable.

Here's what I've put together anyway, your help is very much appreciated :)

Cheers

Tim

/// Start Test1ViewController.h ///
#import <UIKit/UIKit.h>

@interface Test1ViewController : UIViewController {
 UILabel* label;
}
@property (assign) IBOutlet UILabel *label;
@end
/// End Test1ViewController.h ///

/// Start Test1ViewController.m ///
#import "Test1ViewController.h"
#import "MyClass.h"
@implementation Test1ViewController
@synthesize label;
- (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 label.text = @"1";
 [NSThread detachNewThreadSelector:@selector(backgroundProcess) toTarget:self withObject:nil];
}

- (void)backgroundProcess {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  

 // Create an instance of a class that will eventually store a whole load of variables
 MyClass *aMyClassInstance = [MyClass new]; [aMyClassInstance createMyClassInstance:(@"Timbo")];

 while (aMyClassInstance.myVariable--) {
  NSLog(@"blah = %i",aMyClassInstance.myVariable);
  label.text = [NSString stringWithFormat:@"blah = %d", aMyClassInstance.myVariable];

  //how do I pass the new value out to the updateLabel method, or reference aMyClassInstance.myVariable?
  [self performSelectorOnMainThread:@selector(updateLabel) withObject:nil waitUntilDone:NO]; 

  //the sleeping of the thread is absolutely mandatory and must be worked around.  The whole point of using NSThread is so I can have sleeps

  [NSThread sleepForTimeInterval:1];
 }
 [pool release];
}

- (void)updateLabel {label.text = [NSString stringWithFormat:@"blah = %d", aMyClassInstance.myVariable]; // be nice if i could }
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}
- (void)viewDidUnload {}
- (void)dealloc {[super dealloc];}
@end
/// End Test1ViewController.m ///

/// Start MyClass.h ///
#import <Foundation/Foundation.h>
@interface MyClass : NSObject {
 NSString* name;
 int myVariable;
}
@property int myVariable;
@property (assign) NSString *name;
- (void) createMyClassInstance: (NSString*)withName;
- (int) changeVariable: (int)toAmount;
@end
/// End MyClass.h ///

/// Start MyClass.h ///
#import "MyClass.h"
@implementation MyClass
@synthesize name, myVariable;
- (void) createMyClassInstance: (NSString*)withName{
 name = withName;
 myVariable = 10;
}
- (int) changeVariable: (int)toAmount{ 
 myVariable = toAmount;
 return toAmount;
}
@end
/// End MyClass.h ///
A: 

You can wrap the myVariable value when passing it to the main thread like this:

[self performSelectorOnMainThread:@selector(updateLabel:) withObject:[NSNumber numberWithInt:aMyClassInstance.myVariable] waitUntilDone:NO]; 

Then, you have to slightly modify the updateLabel method like this:

- (void)updateLabel:(NSNumber *)arg {
    int value = [arg intValue];
    label.text = [NSString stringWithFormat:@"blah = %d", value];
}

Hope it helps.

Laurent Etiemble
ooh brilliant, i'll try that out tomorrow when I'm back in the office :)
Timbo
That works a treat Laurent. I'm guessing I can use NSDictionary if I need to pass multiple variables to the update label method too. Thanks a million
Timbo