knowledge-database (beta)

Current group: comp.lang.objective-c

modal panel (NSRunAlertPanel) doesn't get closed

modal panel (NSRunAlertPanel) doesn't get closed  
ettore
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
Michael Ash
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
ettore
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
Michael Ash
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
e
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
Michael Ash
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
e
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
e
 Re: modal panel (NSRunAlertPanel) doesn't get closed  
Michael Ash
From:ettore
Subject:modal panel (NSRunAlertPanel) doesn't get closed
Date:Tue, 28 Dec 2004 19:59:51 GMT
I occasionally experience a problem with modal alert panels. I create one with:

NSRunAlertPanel(alertTitle, alertMsg, @"Understood", nil, nil);

where alertTitle and alertMsg are 2 NSStrings correctly created with
[NSString stringWithFormat: ...].

The problem is that very rarely, with no reproducible pattern, the
panel doesn't get closed once the user clicks on the button. It just
sits there. The application reacts as the panel has been closed,
because I am even able to select other windows and fully use the app as
if the panel was closed. When the application needs to open another
alert panel (created with the same call) the old one is finally closed
but the new one takes its place, with an identical behavior.

My application is a document based application - I am not sure what
other information I should provide because the function call seems
straightforward, and I don't know what can be related to it..... did
anybody ever experience this?

Thank you in advance.

Ettore
From:Michael Ash
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Wed, 29 Dec 2004 04:54:05 -0600
ettore wrote:
> I occasionally experience a problem with modal alert panels. I create one with:
>
> NSRunAlertPanel(alertTitle, alertMsg, @"Understood", nil, nil);
>
> where alertTitle and alertMsg are 2 NSStrings correctly created with
> [NSString stringWithFormat: ...].

I don't know if this is actually causing your problem, but here goes.

You should never pass an arbitrary string as the alertMsg in
NSRunAlertPanel. It expects alertMsg to be a format string, with the
arguments for it to follow the otherButton title. If alertMsg happens to
have any format string escapes in it, NSRunAlertPanel will try to decode
them and bizarre things could happen. Try changing your code like this:

NSRunAlertPanel(alertTitle, @"%@", @"Understood", nil, nil, alertMsg);

If that doesn't fix it, watch your run log/debugger console to see if any
messages are appearing.
From:ettore
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Thu, 30 Dec 2004 08:34:50 GMT
On 2004-12-29 02:54:05 -0800, Michael Ash said:

> You should never pass an arbitrary string as the alertMsg in
> NSRunAlertPanel. It expects alertMsg to be a format string, with the
> arguments for it to follow the otherButton title. If alertMsg happens
> to have any format string escapes in it, NSRunAlertPanel will try to
> decode them and bizarre things could happen. Try changing your code
> like this:
>
> NSRunAlertPanel(alertTitle, @"%@", @"Understood", nil, nil, alertMsg);

Thank you for this, I didn't consider it.

Well, the way I wrote my code should make it so that my alertMsg string
(2nd parameter of NSRunAlertPanel) is never supposed to be a format
string: in other words, if it happens to be, it's a non-wanted buggy
behavior. So, if I understand your suggestion correctly, is your advice
just a safe precaution in case there's a bug in my code? In fact I
checked the Apple documentation and both A. Hillegaas' book "Cocoa
Programming for Mac OS X" and "Cocoa Programming" by
Anguish/Buck/Yacktman but I was unable to find an official
recommendation to do so.

Anyway, I will give it a try. :)


> If that doesn't fix it, watch your run log/debugger console to see if
> any messages are appearing.

Yes, I'll definitively keep an eye there and possibly print the
alertMSg string.

Ettore

--
http://cubelogic.org/
Please support Free Software: http://www.gnu.org/philosophy/
From:Michael Ash
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Thu, 30 Dec 2004 15:55:55 -0600
ettore wrote:
> On 2004-12-29 02:54:05 -0800, Michael Ash said:
>
>> You should never pass an arbitrary string as the alertMsg in
>> NSRunAlertPanel. It expects alertMsg to be a format string, with the
>> arguments for it to follow the otherButton title. If alertMsg happens
>> to have any format string escapes in it, NSRunAlertPanel will try to
>> decode them and bizarre things could happen. Try changing your code
>> like this:
>>
>> NSRunAlertPanel(alertTitle, @"%@", @"Understood", nil, nil, alertMsg);
>
> Thank you for this, I didn't consider it.
>
> Well, the way I wrote my code should make it so that my alertMsg string
> (2nd parameter of NSRunAlertPanel) is never supposed to be a format
> string: in other words, if it happens to be, it's a non-wanted buggy
> behavior. So, if I understand your suggestion correctly, is your advice
> just a safe precaution in case there's a bug in my code? In fact I
> checked the Apple documentation and both A. Hillegaas' book "Cocoa
> Programming for Mac OS X" and "Cocoa Programming" by
> Anguish/Buck/Yacktman but I was unable to find an official
> recommendation to do so.

So barring the possibility of bugs, alertMsg will never contain a %
character? Even something like "23% done" will cause strange behavior as
the format string parser picks up "% d" and tries to replace it with an
integer from the nonexistent argument list.

Anyway, specifying @"%@" and then putting your string in the argument list
is always safer in this kind of situation. Even if you're completely sure
that there will never be any format string characters, that could change
after you forgot about this bit of code.

My suggestion wasn't based on the expectation that you're doing something
wrong here, it's just the only possibility I could see.
From:e
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Wed, 12 Jan 2005 11:26:01 GMT
>ettore wrote:
>> On 2004-12-29 02:54:05 -0800, Michael Ash said:
>>
>>> You should never pass an arbitrary string as the alertMsg in
>>> NSRunAlertPanel. It expects alertMsg to be a format string, with the
>>> arguments for it to follow the otherButton title. If alertMsg happens
>>> to have any format string escapes in it, NSRunAlertPanel will try to
>>> decode them and bizarre things could happen. Try changing your code
>>> like this:
>>>
>>> NSRunAlertPanel(alertTitle, @"%@", @"Understood", nil, nil, alertMsg);
>>
>> Thank you for this, I didn't consider it.
>>
>> Well, the way I wrote my code should make it so that my alertMsg string
>> (2nd parameter of NSRunAlertPanel) is never supposed to be a format
>> string: in other words, if it happens to be, it's a non-wanted buggy
>> behavior. So, if I understand your suggestion correctly, is your advice
>> just a safe precaution in case there's a bug in my code? In fact I
>> checked the Apple documentation and both A. Hillegaas' book "Cocoa
>> Programming for Mac OS X" and "Cocoa Programming" by
>> Anguish/Buck/Yacktman but I was unable to find an official
>> recommendation to do so.
>
>So barring the possibility of bugs, alertMsg will never contain a %
>character? Even something like "23% done" will cause strange behavior as
>the format string parser picks up "% d" and tries to replace it with an
>integer from the nonexistent argument list.
>
>Anyway, specifying @"%@" and then putting your string in the argument list
>is always safer in this kind of situation. Even if you're completely sure
>that there will never be any format string characters, that could change
>after you forgot about this bit of code.
>
>My suggestion wasn't based on the expectation that you're doing something
>wrong here, it's just the only possibility I could see.
>.


I implemented your suggestions but the problem is still there. I think
there are problems with run loops. Basically, I have 3 timers: a main
timer, a warning timer (firing some X seconds before the main timer, and a
countdown timer updating a text field every second. The main and the
warning timer may open alerts with NSRunAlertPanel. The alert is open
inside the fire method, so I add the timers to the NSModalPanelRunLoopMode
too. This is my current code:
- (void)startTimer
{
// .....
t = [[NSTimer alloc] initWithFireDate:fireDate
interval:repeatSecs
target:self
selector:@selector(doGestures:)
userInfo:userInfo
repeats:repeatFlag];
currRunLoop = [NSRunLoop currentRunLoop];
[currRunLoop addTimer:t forMode:NSDefaultRunLoopMode];
[currRunLoop addTimer:t forMode:NSModalPanelRunLoopMode];

t2 = [[NSTimer alloc] initWithFireDate:warnFireDate
interval:repeatSecs
target:self
selector:@selector(doGestures:)
userInfo:userInfo2
repeats:repeatFlag];
[currRunLoop addTimer:t2 forMode:NSDefaultRunLoopMode];
[currRunLoop addTimer:t2 forMode:NSModalPanelRunLoopMode];

ut = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(updCountdown:)
userInfo:userInfo3
repeats:YES];
[currRunLoop addTimer:ut forMode:NSModalPanelRunLoopMode];

// ....

}


- (void)doGestures:(NSTimer *)aTimer
{
// construct alertMsg and alertMsg2
// ...

if (isWarning)
{
NSRunAlertPanel(alertTitle2, @"%@", @"Ok", nil, nil, alertMsg2);
if (isLastRepetition)
{
[t2 invalidate];
[t2 release];
t2 = nil;
}
}
else
{
NSRunAlertPanel(alertTitle, @"%@", @"Ok", nil, nil, alertMsg);
if (isLastRepetition)
{
[t invalidate];
[t release];
t = nil;
[ut invalidate];
[ut release];
ut = nil;
}
}

// ....
}

Does anybody see anything wrong with this code?

As mentioned in previous msgs, the alert sometimes doesn't get closed
although the app seems to exit from the modal loop, since I am able to use
the app normally as the alert was closed.
Any insight would be really appreciated. The only thing I can think of
is make my own alert window and take care of closing it, but I don't
understand why the above code sometimes fails.
--Ettore

From:Michael Ash
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Wed, 12 Jan 2005 12:28:42 -0600
e wrote:
>
> I implemented your suggestions but the problem is still there. I think
> there are problems with run loops. Basically, I have 3 timers: a main
> timer, a warning timer (firing some X seconds before the main timer, and a
> countdown timer updating a text field every second. The main and the
> warning timer may open alerts with NSRunAlertPanel. The alert is open
> inside the fire method, so I add the timers to the NSModalPanelRunLoopMode
> too. This is my current code:
[snip]

You're adding doGestures: to the modal runloop mode, and it looks like it
will fire while NSRunAlertPanel is waiting for a response. When it fires,
it calls NSRunAlertPanel. This is a bad combination. NSRunAlertPanel is
probably not reentrant, and the fact that you're calling it while it's
already waiting for a response is probably the reason for your problems.
From:e
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Sat, 15 Jan 2005 07:12:44 GMT
On 2005-01-12 10:28:42 -0800, Michael Ash said:

> e wrote:
>>
>> I implemented your suggestions but the problem is still there. I think
>> there are problems with run loops. Basically, I have 3 timers: a main
>> timer, a warning timer (firing some X seconds before the main timer, and a
>> countdown timer updating a text field every second. The main and the
>> warning timer may open alerts with NSRunAlertPanel. The alert is open
>> inside the fire method, so I add the timers to the NSModalPanelRunLoopMode
>> too. This is my current code:
> [snip]
>
> You're adding doGestures: to the modal runloop mode, and it looks like
> it will fire while NSRunAlertPanel is waiting for a response. When it
> fires, it calls NSRunAlertPanel. This is a bad combination.
> NSRunAlertPanel is probably not reentrant, and the fact that you're
> calling it while it's already waiting for a response is probably the
> reason for your problems.

originally I was not adding the timers to the modal run loop; then I
did so after reading some cocoa boards, for instance:

http://lists.apple.com/archives/cocoa-dev/2005/Jan/msg00370.html
http://lists.apple.com/archives/cocoa-dev/2005/Jan/msg00376.html

After adding the timers to the modal run loop it's much harder to
replicate the bug, and it happened to me only twice (after many many
tests).

I am not aware if NSRunAlertPanel is reentrant or not, but the docs
don't mention it. If it is not reentrant, of course weird behaviors can
happen. Why do you say it's "probably" not reentrant? I could rewrite
NSRunAlertPanel making sure everything is reentrant, but I fail to
understand what I am doing wrong.

Anyway, when a modal panel is open and NSRunAlertPanel is called again,
what happens is that another panel simply opens. Then I am usually
able to close all of them. Why is this a bad combination? Do you have
a specific example or pointer to the documentation that suggests that?

Any other insights? Thank you again.
From:e
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Sat, 15 Jan 2005 02:37:11 GMT
>e wrote:
>>
>> there are problems with run loops. Basically, I have 3 timers: a main
>> timer, a warning timer (firing some X seconds before the main timer, and a
>> countdown timer updating a text field every second. The main and the
>> warning timer may open alerts with NSRunAlertPanel. The alert is open
>> inside the fire method, so I add the timers to the NSModalPanelRunLoopMode
>> too.
>[snip]
>
>You're adding doGestures: to the modal runloop mode, and it looks like it
>will fire while NSRunAlertPanel is waiting for a response. When it fires,
>it calls NSRunAlertPanel. This is a bad combination. NSRunAlertPanel is
>probably not reentrant, and the fact that you're calling it while it's
>already waiting for a response is probably the reason for your problems.

originally I was not adding the timers to the modal run loop; then I did
so after reading some cocoa boards, for instance:
http://lists.apple.com/archives/cocoa-dev/2005/Jan/msg00370.html
http://lists.apple.com/archives/cocoa-dev/2005/Jan/msg00376.html

After adding the timers to the modal run loop it's much harder to
replicate the bug, and it happened to me only twice (after many many tests).
I am not aware if NSRunAlertPanel is reentrant or not, but the docs
don't mention it. If it is not reentrant, of course weird behaviors can
happen. Why do you say it is "probably" not reentrant? I could rewrite
NSRunAlertPanel making sure everything is reentrant, but I fail to understand
what I am doing wrong.
Anyway, when a modal panel is open and NSRunAlertPanel is called again,
what happens is that another panel simply opens. Then I am usually able
to close all of them. Why is this a bad combination? Do you have a
specific example or pointer to the documentation that suggests that?
Any other insights? Thank you again.



From:Michael Ash
Subject:Re: modal panel (NSRunAlertPanel) doesn't get closed
Date:Sat, 15 Jan 2005 03:00:43 -0600
e wrote:
>
> I am not aware if NSRunAlertPanel is reentrant or not, but the docs
> don't mention it. If it is not reentrant, of course weird behaviors can
> happen. Why do you say it is "probably" not reentrant?

Because it's not mentioned on Apple's page on thread-safety as being
reentrant:

http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/articles/CocoaSafety.html

Also, the documentation explicitly states that it reuses its panel rather
than creating a new one each time. If that is always the case, then it
will be using a panel that's already in use when you re-enter it, and I
can't imagine it being good. I say "probably" because nothing explicitly
says it's *not* reentrant, but that doesn't mean much.

> I could rewrite
> NSRunAlertPanel making sure everything is reentrant, but I fail to understand
> what I am doing wrong.
> Anyway, when a modal panel is open and NSRunAlertPanel is called again,
> what happens is that another panel simply opens. Then I am usually able
> to close all of them. Why is this a bad combination? Do you have a
> specific example or pointer to the documentation that suggests that?
> Any other insights? Thank you again.

Nothing more than the above. It's just a guess.
   

Copyright © 2006 knowledge-database   -   All rights reserved