1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

[Cocoa] Binding und Thread

Dieses Thema im Forum "OS X-Developer" wurde erstellt von Josa, 10.07.09.

  1. Josa

    Josa Tydemans Early Worcester

    Dabei seit:
    31.01.07
    Beiträge:
    388
    Ich hoffe mir kann jemand bei meinem Probel helfen.

    Ich möchte das in einen Status Menu eine Wert regelmäßig erneuert wird. Ich habe dafür einen Worker-Thread der einen String in einer Schleife ändert. ein Menu Item ist an den String gebunden (Binding: Controller.foo).

    Das funktioniert soweit auch. Das Problem ist nur, dass ich das Programm aufhängt wenn das Menu geöffnet ist und der String (foo) geändert wird.

    Wie kann ich das verhindern?

    Controller.h
    Code:
    #import <Cocoa/Cocoa.h>
    
    @interface Controller : NSObject {
        
        IBOutlet NSMenu *mainMenu;
        NSStatusItem *mainItem;
        NSString* foo;
    
    }
    
    - (NSString*) foo;
    - (void) setFoo: (NSString*)x;
    + (void) count: (id)param;
    
    @end
    
    Controller.m
    Code:
    #import "Controller.h"
    
    
    @implementation Controller
    
    - (void) awakeFromNib {
        
        mainItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:-1] retain];
        [mainItem setTitle:@"test"];
        [mainItem setMenu:mainMenu];
        [mainItem setHighlightMode:YES];
        
        [NSThread detachNewThreadSelector:@selector(count:) toTarget:[Controller class] withObject:self];
    }
    
    - (NSString *) foo {
        NSLog(@"Get foo: %@", foo);
        return foo;
    }
    
    - (void) setFoo: (NSString *)x {
        NSLog(@"Set foo: %@", x);
        foo = x;
    }
    
    +(void)count:(id)param {
        NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
        int i = 0;
        while (i < 100) {
            [(Controller*)param setFoo: [NSString stringWithFormat:@"foo: %d", i++] ];
            sleep(1);
        }
        [autoreleasepool release];
    }
    
    @end
    
    Console:
    Code:
    [Session started at 2009-07-10 13:02:15 +0200.]
    2009-07-10 13:02:16.176 MenuTest[7700:10b] Get foo: (null)
    2009-07-10 13:02:16.198 MenuTest[7700:390b] Set foo: foo: 0
    2009-07-10 13:02:16.201 MenuTest[7700:390b] Get foo: foo: 0
    2009-07-10 13:02:17.202 MenuTest[7700:390b] Set foo: foo: 1
    2009-07-10 13:02:17.213 MenuTest[7700:390b] Get foo: foo: 1
    2009-07-10 13:02:18.214 MenuTest[7700:390b] Set foo: foo: 2
    2009-07-10 13:02:18.214 MenuTest[7700:390b] Get foo: foo: 2
    
    [Session started at 2009-07-10 13:02:18 +0200.]
    Loading program into debugger…
    GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i386-apple-darwin".Program loaded.
    sharedlibrary apply-load-rules all
    Attaching to program: `/Users/josa/Desktop/MenuTest/build/Debug/MenuTest.app/Contents/MacOS/MenuTest', process 7700.
    [Switching to process 7700 thread 0x390b]
    kill
    
     
  2. LittlePixel

    LittlePixel Strauwalds neue Goldparmäne

    Dabei seit:
    09.07.08
    Beiträge:
    641
    Ich habe Deinen Code nur überflogen.
    Bist Du neu in der Materie? (siehe Setter + Getter)

    Warum einen neuen Thread anlegen?
    Erzeuge einen Timer, der alle paar Sekunden losgeht.

    Viele Grüße
     
  3. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Änderungen am GUI darf man auch nur vom Main-Thread aus machen. Daher gibt es auch eine Methode performSelectorOnMainThread:withObject:waitUntilDone:. Aber der Timer ist hier einfach die bessere Lösung.

    MacApple
     
  4. Josa

    Josa Tydemans Early Worcester

    Dabei seit:
    31.01.07
    Beiträge:
    388
    Danke für die Antworten. Ich werde mir den Timer mal anschauen.

    @LittlePixel Wirklich Erfahrung habe ich mit Objective-C und Cocoa wirklich noch nicht...
     
  5. Josa

    Josa Tydemans Early Worcester

    Dabei seit:
    31.01.07
    Beiträge:
    388
    Das funktioniert so schon mal. Nur wird jetzt der Menu-Item-Title nicht mehr aktualisiert wenn das Menu geöffnent ist. Wie könnte ich das lösen?

    Controller.m
    Code:
    #import "Controller.h"
    
    
    @implementation Controller
    
    - (void) awakeFromNib {
        
        mainItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:-1] retain];
    	[mainItem setTitle:@"test"];
        [mainItem setMenu:mainMenu];
        [mainItem setHighlightMode:YES];
    	
    	timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(count:) userInfo:NULL repeats:YES];
    }
    
    - (IBAction) quite: (id) sender {
    	[NSApp terminate: sender];
    }
    
    - (NSString *) foo {
    	return foo;
    }
    
    - (void) setFoo: (NSString *)x {
    	foo = x;
    }
    
    - (void) count: (NSTimer*) countTimer {
    	[self setFoo: [NSString stringWithFormat:@"foo: %d", i++] ];
    }
    
    @end
    
     
  6. LittlePixel

    LittlePixel Strauwalds neue Goldparmäne

    Dabei seit:
    09.07.08
    Beiträge:
    641
    Siehe NSRunLoop.

    Ich habe es Dir schnell gebaut.
    Siehe Anhang.

    Viele Grüße
     

    Anhänge:

    • Test.zip
      Dateigröße:
      53,9 KB
      Aufrufe:
      67
    Josa gefällt das.
  7. LittlePixel

    LittlePixel Strauwalds neue Goldparmäne

    Dabei seit:
    09.07.08
    Beiträge:
    641
    Ach ja, freigeben musst Du die Objekte mit dealloc selbst ;)

    Bitte lies noch etwas zu Setter und Getter.

    Viele Grüße
     
  8. Irgendein Held

    Irgendein Held Oberösterreichischer Brünerling

    Dabei seit:
    17.06.07
    Beiträge:
    714
    Zum Beispiel das man mit Getter und Setter nicht unsinnig um sich werfen soll ;)
     
  9. LittlePixel

    LittlePixel Strauwalds neue Goldparmäne

    Dabei seit:
    09.07.08
    Beiträge:
    641
    Man kann es auch ordentlich schreiben ;)
    Aber sonst wird ihm langweilig.

    Viele Grüße
     
  10. Josa

    Josa Tydemans Early Worcester

    Dabei seit:
    31.01.07
    Beiträge:
    388
    Danke für die Antworten! Das funktioniert einwandfrei so.
     
  11. Poljpocket

    Poljpocket Salvatico di Campascio

    Dabei seit:
    07.01.07
    Beiträge:
    432
    @Josa, schau dir auch mal das Memory Management System von Objective-C an... denn in deinem Code machst du einige Fehler... :)

    Gruss ppocket
     
  12. Josa

    Josa Tydemans Early Worcester

    Dabei seit:
    31.01.07
    Beiträge:
    388
    Danke für den Tipp, dass werde ich machen.

    Momentan ging es mir aber so wie so erstmal nur um das beschriebene Problem.
     
  13. Jamsven

    Jamsven London Pepping

    Dabei seit:
    21.11.07
    Beiträge:
    2.046
  14. Jamsven

    Jamsven London Pepping

    Dabei seit:
    21.11.07
    Beiträge:
    2.046
    Muss man nicht, wenn man den Garbage Collector anwirft. ;)
     

Diese Seite empfehlen