Run NSRunLoop in a Cocoa command-line program
Is it possible to initialize a NSRunLoop
without loading any NIB files (i.e., without calling NSApplicationMain()
)?
Thanks.
Solution 1:
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
Solution 2:
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
Solution 3:
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
.
Solution 4:
// 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;
}
Solution 5:
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]]);