Reputation: 528
In my app, I have my main file that creates a new instance of a class and then uses NSOperationQueue to run the class functions in the background, like so:
NSOperationQueue backgroundQueue = [NSOperationQueue new];
MyClass mc = [MyClass alloc];
NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:mc selector:@selector(runEvents) object:nil];
[backgroundQueue addOperation:operation];
MyClass then does stuff in RunEvents, but I'm having difficulty passing data to the UI. I'm just trying to update a label on my storyboard, which I can do in my main class that calls MyClass, but how do I update it from MyClass?
Upvotes: 2
Views: 899
Reputation: 437907
The typical answer is to create your class as a NSOperation
subclass and give it a custom completion block. If your goal is update the UI or some model object in the completion block, make sure to dispatch that block back to the main queue:
// CustomOperation.h
#import <Foundation/Foundation.h>
typedef void(^CustomOperationCompletion)(NSString *string);
@interface CustomOperation : NSOperation
@property (nonatomic, copy) CustomOperationCompletion customOperationCompletion;
- (id)initWithCustomCompletion:(CustomOperationCompletion)completion;
@end
and
// CustomOperation.m
#import "CustomOperation.h"
@implementation CustomOperation
- (id)initWithCustomCompletion:(CustomOperationCompletion)completion {
self = [super init];
if (self) {
self.customOperationCompletion = completion;
}
return self;
}
- (void)main {
NSLog(@"%s starting", __FUNCTION__);
sleep(5);
NSString *string = [[NSDate date] description];
if (self.customOperationCompletion) {
[[NSOperationQueue mainQueue] addOperationWithBlock: ^{
self.customOperationCompletion(string);
}];
}
NSLog(@"%s ending", __FUNCTION__);
}
@end
Then you can invoke it with something like:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
CustomOperation *operation = [[CustomOperation alloc] initWithCustomCompletion:^(NSString *string) {
// update the UI with the results of the operation; here I'm just going to log it
NSLog(@"all done, string=%@", string);
}];
[queue addOperation:operation];
Clearly, change your CustomOperationCompletion
parameters to include whatever you want to return (I'm just passing a string back).
Upvotes: 2