On Nov 11, 2010, at 10:35 AM, jonat...@mugginsoft.com wrote:

> 
> On 11 Nov 2010, at 07:13, Shane wrote:
> 
>> I've got an NSOperation thread running, but I'd like to be able to
>> send a message to it so that the thread can be shut it down, or
>> possibly other commands.
>> 
>> What is considered a good way to send a message to an NSOperation
>> thread from the apps main thread?
>> _______________________________________________
>> 
> 
> NSOperation is a great way to schedule a distinct and largely none 
> interacting operation.
> It is not a universal concurrency solution.
> 
> I would drop down to NSThread in this situation.
Please checkout the Apple iOS example application "TopSongs". This is a 
nontrivial example using a NSURLConnection within an operation which exactly 
does what you think would only be doable when using NSThread.  :)


> You have to do a bit more management but you get the control you need.
IMHO, using NSOperation/NSOperationQueue is exactly what I consider a higher 
level API. It has also additional cool features which give you even more 
control where NSThread doesn't provide such things at all. So, for me in many 
cases it's much more easier to use NSOperations than implementing the same 
thing using NSThread.

> 
> Also NSOperation generated threads do not, IIRC, instantiate a run loop.
The thread executing an NSOperation scheduled from an NSOperationQueue already 
has a run loop :) But of course you need to use it, see example below.

> If you want to message your thread using performSelector:onThread you will 
> need a run loop.
In case you would like to do similar things when using NSOperation and 
NSOperationQueue you might consider to send the message to the run loop 
instead, e.g.: -performSelector:target:argument:order:modes:

Of course you would need a mechanism to get the corresponding run loop for that 
operation. I would suggest to define a property in your custom operation and 
set it when the operation enters its main method.



Example for using a run loop in a NSOperation:

- (void) main 
{
    if ([self isCancelled]) {
        return;
    }
    
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];    
    
    // Setup the run loop:
    // Add sources or timers, or use something like a NSURLConnection running 
on top of a run loop.
    // In case of a NSURLConnection you would specify self as the delegate of 
the NSURLConnection.
    // For this contrived example, add a dummy mach port to prevent the run 
loop to exit 
    // prematurely, e.g.:
    [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
    
    _done = NO;  // delegate methods would eventually set this to YES, e.g. 
when using a NSURLConnection.
    
    while (![self isCancelled] || _done) {
        // runMode:beforeDate: will block the thread and will only return after 
an input source has 
        // been processed or after the timeout expired (1 s). Since there in 
this example is no 
        // input source that can be processed, the method returns only after 
the timeout expires.
        [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate 
dateWithTimeIntervalSinceNow:1]];
        fprintf(stdout, "."); 
    }
    
    if ([self isCancelled]) {
        // perform undo or cleanup:
        // ...
        [self performSelectorOnMainThread:@selector(didCancel) withObject:nil 
waitUntilDone:NO];
    } else {
        // get the result:
        // ...
        [self performSelectorOnMainThread:@selector(didFinish) withObject:nil 
waitUntilDone:NO];
    }

    return;
}

(In this example, _delegate has been set to the app delegate which handles the 
methods).

- (void) didFinish {
    [_delegate runLoopOperationDidFinish:self]; // required
}

- (void) didCancel {
    if ([_delegate performSelector:@selector(runLoopOperationCancelled:)]) {
        [_delegate runLoopOperationCancelled:self];
    }
}


You can cancel the NSOperation by sending it the message -cancel. E.g., the app 
delegate sends it in response to a menu action.


Regards,
Andreas

> 
> Regards
> 
> Jonathan Mitchell
> 
> Developer
> Mugginsoft LLP
> http://www.mugginsoft.com

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to