2010-01-28 19 views

Respuesta

11

Sí; puede escribir su propio método principal y ejecutar NSRunLoop sin regresar de NSApplicationMain.

Echa un vistazo a este link; este tipo está usando NSRunLoop en su método principal, aunque no está cargando archivos NIB, pero debería funcionar con NSRunloops.

+0

Vea también: el oficial [documentación de NSRunLoop] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class) – lindes

14

La solución es invocar NSApplication manualmente. Crear delegado de la aplicación en primer lugar de reemplazar el NSApplicationMain() en main.m con lo siguiente:

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

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

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

[pool drain]; 

[delegate release]; 

El delegado será invocado cuando esté listo, sin necesidad de una punta

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

No hay razón por la que uno necesariamente necesite usar NSApplication (y así introducir una dependencia en AppKit); todo esto se puede hacer con NSRunLoop. Como tal, si bien esta es información potencialmente útil para alguien, creo que es una respuesta inapropiada a esta pregunta. Votar abajo por esa razón. – lindes

+0

Estaba usando [[NSRunLoop currentRunLoop] run]; en mi aplicación sin GUI, pero mi aplicación entraba en estado de no respuesta. Este método está funcionando bien para mí. –

+0

no funcionará para ARC – user2159978

5

Para consultar asynctask.m que ejecuta un NSRunLoop manualmente para habilitar el uso de notificaciones asincrónicas "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]; 
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

sigue las recomendaciones de la documentación para [NSRunLoop RUN]:

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

En Swift, se puede lograr esto añadiendo la siguiente línea al final de su main.swift:

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

Si desea poder detener el ciclo de ejecución, debe usar los métodos de Core Foundation.

CFRunLoopRun(); // start 

Y puede detenerlo como esto

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

Esto es genial ... ahora no sé cómo parar, sin embargo. Tienes alguna sugerencia para mi? – cdf1982

+1

actualizó mi respuesta –

Cuestiones relacionadas