Запустите NSRunLoop в программе командной строки Какао - PullRequest
21 голосов
/ 28 января 2010

Возможно ли инициализировать NSRunLoop без загрузки каких-либо файлов NIB (т.е. без вызова NSApplicationMain())?

Спасибо.

Ответы [ 6 ]

15 голосов
/ 28 января 2010

Решение состоит в том, чтобы вызвать NSApplication вручную.Сначала создайте свой делегат приложения, а затем замените вызов NSApplicationMain () в main.m следующим:

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

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

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

[pool drain];

[delegate release];

Делегат будет вызван, когда будет готов, без необходимости ввода nib

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
14 голосов
/ 07 марта 2015

В Swift вы можете добиться этого, добавив следующую строку в конец вашего main.swift:

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

Если вы хотите остановить цикл выполнения, вы должны использовать методы Core Foundation.

CFRunLoopRun(); // start

И ты можешь остановить это вот так

CFRunLoopStop(CFRunLoopGetCurrent()); // stop
12 голосов
/ 28 января 2010

Да; Вы можете написать свой собственный метод main и запустить NSRunLoop, не возвращаясь с NSApplicationMain.

Посмотрите на эту ссылку ; этот парень использует NSRunLoop в своем основном методе, хотя он не загружает файлы NIB, но он должен заставить вас работать с NSRunloops.

8 голосов
/ 13 июня 2013
// 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;
}
7 голосов
/ 03 октября 2014

Следуйте рекомендациям в документации по [NSRunLoop run]:

BOOL shouldKeepRunning = YES;        // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate     distantFuture]]);
5 голосов
/ 28 января 2011

Посмотрите на asynctask.m, который запускает NSRunLoop вручную включить использование асинхронных уведомлений "waitForDataInBackgroundAndNotify".

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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...