Можно ли инициализировать NSRunLoop
без загрузки каких-либо файлов NIB (т.е. без вызова NSApplicationMain()
)?
Спасибо.
Можно ли инициализировать NSRunLoop
без загрузки каких-либо файлов NIB (т.е. без вызова NSApplicationMain()
)?
Спасибо.
Да; вы можете написать свой собственный основной метод и запустить NSRunLoop
, не возвращаясь из NSApplicationMain
.
Посмотрите на ссылку ; этот парень использует NSRunLoop в своем основном методе, но он не загружает файлы NIB, но он должен заставить вас идти с NSRunloops
.
Решение заключается в вызове 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
В Swift вы можете достичь этого, добавив следующую строку в конец вашего main.swift
:
NSRunLoop.currentRunLoop().run(); // Swift < 3.0
RunLoop.current.run(); // Swift >= 3.0
Если вы хотите, чтобы остановить цикл выполнения, вы должны использовать методы Core Foundation.
CFRunLoopRun(); // start
И вы можете остановить его так:
CFRunLoopStop(CFRunLoopGetCurrent()); // stop
// 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;
}
Следуйте рекомендациям в документах для [NSRunLoop run]:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
Посмотрите на 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];