0

Occasionally I have to do a popup alert window in my Cocoa code segments. Previously I used NSAlert directly then have runModal to go while I found that the NSRunAlertPanel is more easier to achieve my goal. So I decided to switch all my alert functions to NSRunAlertPanel. It seemed okay at most time。

Now I'm adding multithreading. I found that NSRunAlertPanel appears clearly slower than NSAlert when calling back in the main thread.

Code segments:

Firstly I create a thread:

[NSThread detachNewThreadSelector: @selector(tryRunLoop:) toTarget:self withObject:nil];

Then this functiontryRunLoop in this thread call the alert window function in the main thread:

while(1)
[self performSelectorOnMainThread:@selector(showAlert:) withObject:anObject waitUntilDone:YES]; 

The function showAlert in main thread do the rest things:

NSRunAlertPanel(@"Warning:",@"Just testing", @"YES", nil, nil);

As time goes by the response of the popup window appears slower and slower.If I use NSAlert instead of NSRunAlertPanel, or did not run the popup method in main thread, the symptom should disappear.

I also found that the CPU usage was also different between these two methods. Obviously NSAlert costs low CPU usage while hitting the button all the time.

Is someone able to explain these phenomenons?

PS: I was not allowed to put the whole original project online so that I've created a simple Cocoa project in Github to simulate the symptom and the URL ,please take a look at the Known issues in Readme file at first.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
othercat
  • 11
  • 2
  • That sounds like some truly insane code. Why spin up a fresh thread just to have it message across to the main thread? – Mike Abdullah Jul 22 '13 at 19:59
  • @MikeAbdullah All the alert messages must be sent to main thread if you want to display Alert windows according to Cocoa development.And you mean a fresh thread in the loop? As a matter of fact I tried it but the situation seems to be the same. – othercat Jul 23 '13 at 03:39
  • Correct, yes, alerts must be run on the main thread. What I don't understand from your code above is why you are detaching a *new* thread as well, which apparently does nothing but message across to the main thread – Mike Abdullah Jul 23 '13 at 16:26
  • @MikeAbdullah The code above is JUST the simple sample from my project to show `NSRunAlertPanel` may have performance issue there.It indeed does nothing but can point out the symptom. – othercat Jul 24 '13 at 00:50
  • OK. It's incredibly hard to tell what you're really after here; having only small random fragments of code doesn't help. You likely need to go back to the drawing board: we generally use queues and `NSAlert` these days in Cocoa, rather than threads and `NSRunAlertPanel`. – Mike Abdullah Jul 24 '13 at 09:05
  • @MikeAbdullah I've already put my sample on Github and have given the URL at the end of my question. To be honest, I don't think the project which I'd written contains ONLY small random fragments of codes.Our QA have reported the performance issue by hitting the AlertPanel continuously so that I made the question and did the sample, just made the `while` loop instead of operating by human beings. – othercat Jul 24 '13 at 14:27

1 Answers1

0

Alright, the short answer is don't use NSRunAlertPanel. That family of functions have been discouraged for some time now, and superseded by NSAlert. Use NSAlert instead.

(Unfortunately the class reference for NSRunAlertPanel etc. doesn't mention this; I'm trying to remember where it was first documented; perhaps a release note)

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
  • 1
    There's a note in the intro to the [NSAlert](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSAlert_Class/Reference/Reference.html) documentation. – JeremyP Jul 24 '13 at 15:34