Anfänger-Frage: NSTask blockiert das GUI

Scherak

Mitglied
Thread Starter
Dabei seit
29.09.2009
Beiträge
38
Reaktionspunkte
1
Hi,

ich habe ziemlich frisch mit Object C angefangen (AppleScript- und AppleScriptStudio-Kenntnisse vorhanden). Bei der Programmierung von einem kleinen Tool bin ich auf das folgende Problem gestoßen:

Das Tool hat ein einfaches GUI mit einem Button (Startbutton) und ein paar Textfelder für die Ausgabe. Bei Klicken auf den Start-Button soll der Button mit setEnbaled=FALSE deaktiviert werden, danach sollen paar Terminalbefehle mit NSTask ausgeführt werden und wenn diese Befehle (find, grep usw) durchgelaufen sind, soll der Start-Button wieder aktivi geschaltet werden.

Das Problem ist aber, dass die Terminalbefehle das GUI so sperren, dass die Deaktivierung vom Start-Button nicht dargestellt werden kann. Zur Veranschaulichung des Problems kurz die folgende Methode (Sleep(5) steht als Stellvertreter für die Terminalbefehle):

Code:
- (IBAction)start:(id)sender {
	[myButton setEnabled:FALSE];
	sleep(10);
        [myButton setEnabled:TRUE];

}

Meine Erwartung war, dass der Button deaktiviert und erst nach 10 Sekunden wieder aktiviert wird und das ist leider nicht der Fall. Wie könnte ich das Problem aus dem Weg gehen?

Viele Grüße, Scherak
 
NSTask blockiert die GUI normal nicht, irgendwas machst du falsch ...
 
Hallo,

Das Problem ist aber, dass die Terminalbefehle das GUI so sperren, dass die Deaktivierung vom Start-Button nicht dargestellt werden kann. Zur Veranschaulichung des Problems kurz die folgende Methode (Sleep(5) steht als Stellvertreter für die Terminalbefehle):
Nö, steht es nicht ;)

Dein "Problem" ist mit dem Stichwort RunLoop zu umreisen.
Belese Dich mal dazu.

Zur Lösung Deines Problems:
- NSTask
- setStandardOutput
- NSFileHandle
- readInBackgroundAndNotify etc.

Ist für den Anfang aber schon nen bissel hardcora.

Man könnte es auch in einen eigenen Thread wursteln. Das ist viel einfacher aber unsauberer in der Umsetzung.

Viele Grüße
 
Beispiel, siehe unten.

Das ist aber für aufwändige Dinge nicht unbedingt zu empfehlen.

Viele Grüße

Code:
-(void)start:(id)sender
{

    // …
    
    [self startUpdateMyInterface:self];
    
    // …
    
    [NSThread detachNewThreadSelector:@selector(somethingToDo:)
                             toTarget:self
                           withObject:self];
    
    // …

}

-(void)startUpdateMyInterface:(id)sender
{

    NSLog(@"böh…");

}

-(void)endUpdateMyInterface:(id)sender
{
    
    NSLog(@"aha…");
    
}

-(void)somethingToDo:(id)sender
{

    // …
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    if(pool == nil)
    {
    
        return;
    
    }
    
    // …
    
    NSLog(@"Hier den Task mit -waitUntilExit nudeln lassen…");
    
    // …
    
    [pool drain];

    // …
    
    [self performSelectorOnMainThread:@selector(endUpdateMyInterface:)
                           withObject:self
                        waitUntilDone:NO];
    
    // …

}
 
Hi,

@ oneOeight: In meinem Beispiel ist aber definitiv so, dass "[myButton setEnabled:FALSE];" erst ausgeführt wird, wenn die 10 Sekunden durch sind und das verstehe ich von der Reihenfolge nicht.

@little_pixel: dein erster Beitrag hat mir einen Schrecken eingejagt. Dein Zweiter gefällt mir aber viel besser, ich werde es ausprobieren, vielen Dank!!

Viele Grüße und ein schönes WE.
 
Guten Morgen little_pixel,

vielen Dank für deine Hilfe, es hat auf Anhieb geklappt.
Es ist unvorstellbar, wie viel Zeit ich -erstmal:D- gespart habe.

Viele Grüße my big_pixel.
 
Zurück
Oben Unten