Is it possible to initialize a NSRunLoop
without loading any NIB files (i.e., without calling NSApplicationMain()
)?
Thanks.
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
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
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]]);
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
.
// 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;
}
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];