Re: NSNotificationCenter and a modal window - a problem
Re: NSNotificationCenter and a modal window - a problem
- Subject: Re: NSNotificationCenter and a modal window - a problem
- From: Ken Thomases <email@hidden>
- Date: Wed, 24 Mar 2010 02:48:16 -0500
On Mar 24, 2010, at 2:11 AM, Alexander Bokovikov wrote:
> [[NSNotificationCenter defaultCenter] addObserver:anObj
> selector:@selector(getData:)
> name:NSFileHandleReadCompletionNotification
> object:[[mytask standardError] fileHandleForReading]];
> [[NSNotificationCenter defaultCenter] addObserver:anObj
> selector:@selector(taskTerminated:)
> name:NSTaskDidTerminateNotification
> object:mytask];
> [[[mytask standardError] fileHandleForReading] readInBackgroundAndNotify];
>
>
> All is going OK when I have a progress bar in the main window, so anObj = self. But I'd like to use just the same code to show a progress of the same NSTask by a NSProgressIndicator, placed in a modal NSPanel, opened through [NSApp runModalForWindow:]. In this case NSTask is launched and is executed OK, And it does what it should. But none of notifications are going to my popup modal window.At least getData method is never called, as debugger shows it.
> What is the problem reason? Is it possible to receive notifications in a modal window?
There are two things going on, and you should be careful not to confuse them.
The first is the monitoring of external "events" or data sources, such as reading from a pipe or monitoring the lifetime of the task. The second is posting a notification.
In this case, both the file handle and the task object post notifications in response to external events/data. However, the posting of the notification is not the problem.
The problem is monitoring the external events/data. That is done via the runloop. If you aren't running the runloop, or aren't running it in the relevant modes, then those objects can never learn about the external events or arrival of data. Since they haven't learned about them, they never even try to post notifications about them.
You need to invoke -readInBackgroundAndNotifyForModes: and pass an array of modes which includes NSModalPanelRunLoopMode (or NSRunLoopCommonModes, which includes NSModalPanelRunLoopMode by default).
I'm not certain what modes NSTask uses to monitor for termination of the task. Since -waitUntilExit runs the run loop in NSDefaultRunLoopMode, I assume it's at least that mode. It may be only that mode, but it's not documented one way or another. So, it's possible that an NSTask can't learn of the termination of its task while the app is running a modal window.
If NSTask does monitor its task in NSModalPanelRunLoopMode, then the reason you may not be getting the notification may be because the task itself is blocked. It may have filled its output pipe. Since you're not reading from that pipe, because the runloop is not running in the right mode for -readInBackgroundAndNotify, the pipe is not getting drained. Once that the pipe is full, the task will block when it tries to write to its output. So, it never completes its work and never exits.
If that's the case, then fixing how you read from the pipe will fix both issues.
Regards,
Ken
_______________________________________________
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