在Cocoa命令行程序中运行NSRunLoop

Ben*_*ves 21 cocoa objective-c

是否可以在NSRunLoop不加载任何NIB文件的情况下初始化(即不调用NSApplicationMain())?

谢谢.

Ben*_*ves 15

解决方案是手动调用NSApplication.首先创建您的应用程序委托,而不是使用以下内容替换main.m中的NSApplicationMain()调用:

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

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

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

[pool drain];

[delegate release];
Run Code Online (Sandbox Code Playgroud)

准备就绪时将调用委托,而不需要笔尖

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
Run Code Online (Sandbox Code Playgroud)

  • 对于ARC,删除[delegate release],[pool drain]和NSAutoreleasePool,并在所有代码周围放置@autoreleasepool {}. (4认同)

Cha*_*ira 14

在Swift中,您可以通过将以下行添加到您的结尾来实现此目的main.swift:

NSRunLoop.currentRunLoop().run();  // Swift < 3.0
RunLoop.current.run();             // Swift >= 3.0
Run Code Online (Sandbox Code Playgroud)

如果您希望能够停止运行循环,则必须使用Core Foundation方法.

CFRunLoopRun(); // start
Run Code Online (Sandbox Code Playgroud)

你可以这样阻止它

CFRunLoopStop(CFRunLoopGetCurrent()); // stop
Run Code Online (Sandbox Code Playgroud)

  • 这很棒......但现在我不知道如何停下来.你有什么建议吗? (2认同)

raz*_*iiq 12

是; 你可以编写自己的主方法并在NSRunLoop不返回的情况下运行NSApplicationMain.

看看这个链接 ; 这家伙在他的主要方法中使用NSRunLoop,虽然他没有加载NIB文件,但它应该让你继续NSRunloops.


rmc*_*hee 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;
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 7

按照[NSRunLoop run]文档中的建议:

BOOL shouldKeepRunning = YES;        // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate     distantFuture]]);
Run Code Online (Sandbox Code Playgroud)


小智 5

看一下手动运行NSRunLoop的asynctask.m,以启用异步"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];
Run Code Online (Sandbox Code Playgroud)