标签: nsrunloop

NSDefaultRunLoopMode与NSRunLoopCommonModes

亲爱的stackoverflow人,

就像上次一样,我特此提出一个我最近偶然发现的问题.我希望那里的某个人可以对我有所了解.

每当我尝试下载一个大文件的背后UIScrollView,MPMapView或者什么的,下载过程被当我触摸iPhone屏幕停止.值得庆幸的是,Jörn的一篇很棒的博客文章提出了一个替代选项,NSRunLoopCommonModes用于连接.

这让我看看两个模式的细节,NSDefaultRunLoopMode和NSRunLoopCommonModes,但苹果文档并没有好好解释,除了说

NSDefaultRunLoopMode

处理NSConnection对象以外的输入源的模式.这是最常用的运行循环模式.

NSRunLoopCommonModes

使用此值作为模式添加到运行循环的对象由已声明为"常用"模式集的成员的所有运行循环模式监视;有关详细信息,请参阅CFRunLoopAddCommonMode的说明.

CFRunLoopAddCommonMode

源,定时器和观察器被注册到一个或多个运行循环模式,并且仅在运行循环以其中一种模式运行时运行.常用模式是一组运行循环模式,您可以为其定义这些模式共享的一组源,定时器和观察器.例如,不是将源注册到每个特定的运行循环模式,而是可以将其注册到运行循环的公共伪模式,并且它将在共模模式集中的每个运行循环模式中自动注册.同样,当将模式添加到该组共用模式时,已经注册到公共伪模式的任何源,定时器或观察者被添加到新添加的共模.

有谁能用人类语言解释这两个?

iphone multithreading nsrunloop ios

105
推荐指数
1
解决办法
3万
查看次数

了解NSRunLoop

谁能解释一下是NSRunLoop什么?所以我知道这NSRunLoop是一件与之相关的事情NSThread吗?所以假设我创建一个类似的线程

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];

-(void) someMethod
{
    NSLog(@"operation");
}
Run Code Online (Sandbox Code Playgroud)

在这个线程完成他的工作之后?为什么使用RunLoops或在哪里使用?从Apple docs我已经阅读了一些东西,但对我来说并不清楚,所以请尽可能简单地解释

cocoa-touch objective-c nsrunloop ios

100
推荐指数
3
解决办法
6万
查看次数

如何在后台线程上创建NSTimer?

我有一项需要每1秒执行一次的任务.目前我每隔1秒就有一次NSTimer重复射击.如何在后台线程(非UI线程)中触发计时器?

我可以在主线程上使用NSTimer激发然后使用NSBlockOperation来调度后台线程,但我想知道是否有更有效的方法来执行此操作.

cocoa objective-c nstimer nsrunloop nsblockoperation

66
推荐指数
6
解决办法
6万
查看次数

如何安排块在下一个运行循环迭代中运行?

我希望能够block在下一个运行循环迭代中执行a .它是否在下一个运行循环的开始或结束时执行并不是那么重要,只是执行被推迟到当前运行循环中的所有代码都已完成执行.

我知道以下内容不起作用,因为它与主运行循环交错,所以我的代码可能会在下一个运行循环中执行,但它可能不会.

dispatch_async(dispatch_get_main_queue(),^{
    //my code
});
Run Code Online (Sandbox Code Playgroud)

以下我认为遇到与上述相同的问题:

dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void){
    //my code
});
Run Code Online (Sandbox Code Playgroud)

现在我相信以下内容可以正常工作,因为它放在当前运行循环的末尾(如果我错了,请纠正我),这实际上有用吗?

[self performSelector:@selector(myMethod) withObject:nil afterDelay:0];
Run Code Online (Sandbox Code Playgroud)

那个有0间隔的计时器怎么样?文档说明:If seconds is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.这是否可以保证在下一次运行循环迭代中执行?

[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(myMethod) userInfo:nil repeats:NO];
Run Code Online (Sandbox Code Playgroud)

这是我能想到的所有选项,但我仍然没有接近于在下一次运行循环迭代中执行一个块(而不是调用方法),并保证它不会更快.

cocoa cocoa-touch objective-c grand-central-dispatch nsrunloop

37
推荐指数
1
解决办法
1万
查看次数

从Swift命令行程序中使用NSURLSession

我想在将它集成到更大的应用程序之前测试一个小概念验证命令行应用程序.我要做的是使用NSURLSession使用此示例下载一些数据.但是,如果我使用简单OS X命令行应用程序中给出的示例,则应用程序会在检索数据之前退出.

如何使用NSURLSession从独立命令行应用程序下载数据?我读到的是使用NSRunLoop但是我还没有在Swift中找到一个明确的例子,所以如果NSRunLoop实际上是要走的路,那么任何例子都会受到赞赏.

从Swift命令行应用程序的URL下载数据的任何其他策略也是受欢迎的(无限循环?).

macos nsrunloop nsurlsession swift

26
推荐指数
3
解决办法
6480
查看次数

保持NSThread存活并在其上运行NSRunLoop

所以我正在开始一个新的NSThread,我希望以后可以通过调用来使用它performSelector:onThread:....根据我的理解,调用方法将该调用添加到该线程上的runloop,因此在下一次迭代时,它将弹出所有这些调用,然后调用它们,直到没有任何东西可以调用.所以我需要这种功能,一个空闲的线程准备工作,我可以调用它.我当前的代码如下所示:

   - (void)doInitialize
   {
       mThread =  [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
       [mthread start];
   }

   - (void)runThread
   {
       NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

       // From what I understand from the Google machine is that this call should start the
       // runloop on this thread, but it DOESN'T. The thread dies and is un-callable
       [[NSRunLoop currentRunLoop] run];

       [pool drain];
   }

   - (void)scheduleSomethingOnThread
   {
       [self performSelector:@selector(hardWork) onThread:mThread withObject:nil waitUntilDone:NO];
   }
Run Code Online (Sandbox Code Playgroud)

但是线程没有保持活动状态,performSelector:onThread没有做任何事情.我该怎么做正确的方法?

cocoa objective-c foundation nsthread nsrunloop

22
推荐指数
2
解决办法
1万
查看次数

如何在使NSTimer失效后"验证"它?

所以基本上,我有这个计时器,它应该在收到一个键事件时重复,并在用户释放键时失效.但是,即使通过调用addTimer:forMode:NSRunLoop ,我也无法"验证"计时器.有谁知道为什么会发生这种情况以及如何解决这个问题?谢谢.

cocoa objective-c nstimer nsrunloop

21
推荐指数
2
解决办法
1万
查看次数

需要对调度队列,线程和NSRunLoop做一些澄清

以下是我所了解和理解的事情:

全局队列是一个并发队列,可以将任务分派给多个线程.执行任务的顺序无法保证.例如:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {
 for (int i; i<10; i++) {
  doTask()
 }
})
Run Code Online (Sandbox Code Playgroud)

如果我想调度到串口队列,我可以使用

dispatch_async(dispatch_queue_create("my.serial.queue", nil) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

每次只有一个任务被分派到一个线程并被执行.订单是FIFO.

=====我感到困惑和不完全理解=======

  1. 主线程有一个NSRunLoop,在主线程中循环任务.我想知道调度队列和运行循环之间的关系是什么?我可以理解它,如果将任务调度到主线程,主线程的NSRunLoop获取调度任务并执行它吗?

  2. 将任务分派给多个线程的全局队列怎么样?iOS/OSX系统是否自动创建线程,还为每个线程创建NSRunLoop?然后每个线程中的运行循环从全局队列中获取调度任务并执行它?

  3. 谁知道线程?do dispatch_async()dispatch_sync()function知道哪个线程要调度任务,或者队列知道哪个线程要调度任务?

  4. 有没有办法以编程方式从调度队列中获取线程的NSRunLoop对象(调度任务的对象)?(这个问题与问题3有关)

multithreading nsthread grand-central-dispatch nsrunloop ios

21
推荐指数
2
解决办法
7698
查看次数

NSTimer要求我将它添加到runloop

我想知道是否有人可以解释为什么调度回主队列并创建重复NSTimer我不得不将它添加到RUN LOOP因为太火了?即使在使用时performselectorOnMainThread我仍然需要将它添加到RUN LOOP以使其触发.

以下是我的问题示例:

#define queue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define mainqueue dispatch_get_main_queue()

- (void)someMethodBeginCalled
{
    dispatch_async(queue, ^{
        int x = 0;
        dispatch_async(mainqueue, ^(void){
            if([_delegate respondsToSelector:@selector(complete:)])
                [_delegate complete:nil];
        });
    });
}

- (void)compelete:(id)object
{
    [self startTimer];

    //[self performSelectorOnMainThread:@selector(startTimer) withObject:nil waitUntilDone:NO];
}

- (void)startTimer
{
    NSTimer timer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(callsomethingelse) userInfo:nil repeats:YES];

    //NSDefaultRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:_busTimer forMode:NSRunLoopCommonModes];
}
Run Code Online (Sandbox Code Playgroud)

编辑: 我相信我措辞很差.如果我打电话,我想知道为什么 [[NSRunLoop currentRunLoop] addTimer:_busTimer forMode:NSRunLoopCommonModes];有必要.如果我不包括该行,则计时器不会触发.startTimersomeMethodBeginCalled

如果我呼吁startTimer来自viewDidLoad例如,我可以删除NSRunLoop线和计时器将每隔60秒射击.

objective-c nstimer nsrunloop ios

19
推荐指数
2
解决办法
2万
查看次数

用GCD运行重复NSTimer?

我想知道为什么当你在GCD块中创建一个重复计时器时它不起作用?

这很好用:

-(void)viewDidLoad{
    [super viewDidLoad];
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
}
-(void)runTimer{
    NSLog(@"hi");
}
Run Code Online (Sandbox Code Playgroud)

但这项工作:

dispatch_queue_t myQueue;

-(void)viewDidLoad{
    [super viewDidLoad];

    myQueue = dispatch_queue_create("someDescription", NULL);
    dispatch_async(myQueue, ^{
        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
    });
}
-(void)runTimer{
    NSLog(@"hi");
}
Run Code Online (Sandbox Code Playgroud)

objective-c nstimer grand-central-dispatch nsrunloop ios

19
推荐指数
1
解决办法
1万
查看次数