Re: NSTask is intermittently failing to return results.
Re: NSTask is intermittently failing to return results.
- Subject: Re: NSTask is intermittently failing to return results.
- From: Jason Harris <email@hidden>
- Date: Sun, 20 Mar 2011 01:38:43 +0100
Answer part II
On Mar 19, 2011, at 8:43 PM, Bill Monk wrote:
> Please, you must stop now, you're going to make yourself nuts. :)
>
> - (void) gotError:(NSNotification*)notification
> {
> ....
> (@"...got NULL Error Output for %@ ...", [self commandLineString]);
> errHandle_ = nil;
> if ([self shouldFinishUp])
> [self finishUp];
>
> Why do you care if the error output is null? Getting a single zero-length NSData from the stdErr pipe is normal if the task completed without error. Why? Because when you call readInBackgroundAndNotify, it calls availableData on the file handle. Docs say availableData "Returns an empty data object if the end of file is reached", so you might get a notification with a zero-length NSData. That is not an indication that the task is finished, or that you should set its stdErr filehandle to nil, or that you should start guessing whether the task it done. It will notify you when it is done.
>
> When you receive your gotError method, just do whatever you want to do with the actual error data. Thats's all. If there's not any data, fine. That does not indicate an error.
>
>
> * When you receive NSTaskDidTerminateNotification, simply believe it. Close up shop. If you want the tasks's status, call terminationStatus. But don't try to guess if it's "really" finished, or "really and truly finished", or "really, truly, for sure, for certain, finished". It is finished.
Uhh no... you are *quite* wrong in that last paragraph. Again look at Moriarty, AMShell, OpenFileKiller, and MyTask. In fact others in this very thread commented on this. Reread some of the others comments about this. The exit notification is *not* enough to exit. It just means that the task finished, it doesn't mean that you have got all the output and or errors yet. You are receiving them asynchronously, and they could, and very often are, out of order.
Please see the other sample codes for examples...
> What you've got here, no:
>
> - (void) gotExit:(NSNotification*)notification
> {
> if (notification)
> DebugLog(@"...got Exit for %@ ...", [self commandLineString]);
> if ([self shouldFinishUp])
> [self finishUp];
> else
> [self setPendingTermination];
> }
>
> If something is happening that makes you think it's not REALLY finished, find and fix THAT bug. All this method needs to do is
>
> Also, why is this doing this?
>
> if (notification)
>
> The method wouldn't be called if there weren't a notification. And all it needs to do is call your finishUp method.
That was in there since eg MyTask calls the finishing method both as a notification and as a way to finish things up. At one stage I did the same. I have been through lots of variants in order to find the right way to do things.
Cheers,
Jas_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden