NSNotificationCenter and a modal window - a problem

2010-03-24 Thread Alexander Bokovikov

Hi, All,

I have a project where a progress of NSTask is indicated through this  
code:


if ([self  popup] != nil)
anObj = [self popup];
else
anObj = self;
[[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.


self is AppController, popup is a subclass of NSWindowController.

What is the problem reason? Is it possible to receive notifications in  
a modal window?


Thanks.

___

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


Re: NSNotificationCenter and a modal window - a problem

2010-03-24 Thread Ken Thomases
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 (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


Re: NSNotificationCenter and a modal window - a problem [solved]

2010-03-24 Thread Alexander Bokovikov


On 24.03.2010, at 12:48, Ken Thomases wrote:

You need to invoke -readInBackgroundAndNotifyForModes: and pass an  
array of modes which includes NSModalPanelRunLoopMode (or  
NSRunLoopCommonModes, which includes NSModalPanelRunLoopMode by  
default).


Many thanks! Really I should look at that method, but I looked at the  
notification center, which has minimum of methods. Don't know why but  
I decided that this aspect should be taken into account when an  
observer is added. Now it's obvious for me, that I should look at the  
notification generator too.


NSTask termination is caught without any problems. The problem was  
just in reading from pipe.


Thanks.
___

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