2010-01-28 11 views

Antwort

11

Ja; Sie können Ihre eigene Hauptmethode schreiben und NSRunLoop ausführen, ohne von NSApplicationMain zurückzukehren.

Werfen Sie einen Blick auf diese link; Dieser Typ verwendet NSRunLoop in seiner Hauptmethode, er lädt jedoch keine NIB-Dateien, aber es sollte Sie mit NSRunloops gehen.

+0

Siehe auch: die offizielle [NSRunLoop Dokumentation] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class) – lindes

14

Die Lösung besteht darin, NSApplication manuell aufzurufen. Erstellen AppDelegate zuerst als die NSApplicationMain ersetzen() aufrufen, in main.m mit den folgenden:

AppDelegate * delegate = [[AppDelegate alloc] init]; 

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

NSApplication * application = [NSApplication sharedApplication]; 
[application setDelegate:delegate]; 
[NSApp run]; 

[pool drain]; 

[delegate release]; 

Der Delegat wird, wenn bereit aufgerufen, ohne eine Feder zu benötigen

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
+1

Es gibt keinen Grund, den man unbedingt braucht die Verwendung von NSApplication (und damit eine Abhängigkeit von AppKit); Dies kann alles mit NSRunLoop geschehen. Obwohl dies für jemanden potenziell nützliche Informationen ist, halte ich das für eine unangemessene Antwort auf diese Frage. Aus diesem Grund abstimmen. – lindes

+0

Ich habe [[NSRunLoop currentRunLoop] run]; in meiner GUI-less-Anwendung, aber meine Anwendung ging in nicht reagierenden Zustand. Diese Methode funktioniert gut für mich. –

+0

funktioniert nicht für ARC – user2159978

5

Werfen Sie einen Blick auf asynctask.m, das einen NSRunLoop manuell ausführt, um die Verwendung von asynchronen "waitForDataInBackgroundAndNotify" Benachrichtigungen zu ermöglichen.

http://www.cocoadev.com/index.pl?NSPipe

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    while(!terminated) 
    { 
    //if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:100000]]) 
    if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) 
    { 
     break; 
    } 
     [pool release]; 
     pool = [[NSAutoreleasePool alloc] init]; 
    } 

    [pool release]; 
8
// Yes. Here is sample code (tested on OS X 10.8.4, command-line). 
// Using ARC: 
// $ cc -o timer timer.m -fobjc-arc -framework Foundation 
// $ ./timer 
// 

#include <Foundation/Foundation.h> 

@interface MyClass : NSObject 
@property NSTimer *timer; 
-(id)init; 
-(void)onTick:(NSTimer *)aTimer; 
@end 

@implementation MyClass 
-(id)init { 
    id newInstance = [super init]; 
    if (newInstance) { 
     NSLog(@"Creating timer..."); 
     _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 
      target:self 
      selector:@selector(onTick:) 
      userInfo:nil 
      repeats:YES]; 
    } 
    return newInstance; 
} 

-(void)onTick:(NSTimer *)aTimer { 
    NSLog(@"Tick"); 
} 
@end 

int main() { 
    @autoreleasepool { 
     MyClass *obj = [[MyClass alloc] init]; 
     [[NSRunLoop currentRunLoop] run]; 
    } 
    return 0; 
} 
6

die Empfehlungen in der Dokumentation Folgen für [NSRunLoop laufen]:

BOOL shouldKeepRunning = YES;  // global 
NSRunLoop *theRL = [NSRunLoop currentRunLoop]; 
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate  distantFuture]]); 
12

In Swift, können Sie dies durch Anhängen die folgende Zeile an das Ende erreichen kann Ihr main.swift:

NSRunLoop.currentRunLoop().run(); // Swift < 3.0 
RunLoop.current.run();    // Swift >= 3.0 

Wenn Sie die Laufschleife anhalten möchten, müssen Sie die Core Foundation-Methoden verwenden.

CFRunLoopRun(); // start 

Und Sie können es wie dieses

CFRunLoopStop(CFRunLoopGetCurrent()); // stop 
+2

Das ist großartig ... jetzt weiß ich nicht, wie ich aufhören soll. Hast du irgendwelche Vorschläge für mich? – cdf1982

+1

aktualisierte meine Antwort –

Verwandte Themen