Run NSRunLoop in a Cocoa command-line program

前端 未结 6 1649
遥遥无期
遥遥无期 2020-11-27 04:20

Is it possible to initialize a NSRunLoop without loading any NIB files (i.e., without calling NSApplicationMain())?

Thanks.

相关标签:
6条回答
  • 2020-11-27 04:45

    The solution is to invoke NSApplication manually. Create your app delegate first than replace the NSApplicationMain() call in main.m with the following:

    AppDelegate * delegate = [[AppDelegate alloc] init];
    
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    NSApplication * application = [NSApplication sharedApplication];
    [application setDelegate:delegate];
    [NSApp run];
    
    [pool drain];
    
    [delegate release];
    

    The delegate will be invoked when ready, without needing a nib

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    
    0 讨论(0)
  • 2020-11-27 04:58

    In Swift, you can achieve this by appending the following line to the end of your main.swift:

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

    If you want to be able to stop the run loop you have to use the Core Foundation methods.

    CFRunLoopRun(); // start
    

    And you can stop it like this

    CFRunLoopStop(CFRunLoopGetCurrent()); // stop
    
    0 讨论(0)
  • 2020-11-27 04:58

    Follow the recommendations in the docs for [NSRunLoop run]:

    BOOL shouldKeepRunning = YES;        // global
    NSRunLoop *theRL = [NSRunLoop currentRunLoop];
    while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate     distantFuture]]);
    
    0 讨论(0)
  • 2020-11-27 05:01

    Yes; you can write your own main method and run NSRunLoop without returning from NSApplicationMain.

    Have a look at this link; this guy is using NSRunLoop in his main method, he is not loading NIB files though, but it should get you going with NSRunloops.

    0 讨论(0)
  • 2020-11-27 05:02
    // 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;
    }
    
    0 讨论(0)
  • 2020-11-27 05:02

    Have a look at asynctask.m that runs an NSRunLoop manually to enable the use of asynchronous "waitForDataInBackgroundAndNotify" notifications.

    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];
    
    0 讨论(0)
提交回复
热议问题