标签: nsrunloop

CFRunLoopRun()vs [NSRunLoop运行]

我有一个NSRunLoop对象,我附加了定时器和流.它很棒.停止它是另一个故事.

我使用循环运行[runLoop run].

如果我尝试停止循环使用CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]),循环将不会停止.如果我使用CRunLoopRun()相反的方式启动循环,它可以工作.我还确保调用是在正确的线程(运行我的自定义运行循环的线程)上进行的.我调试了这个pthread_self().

我找到了一个邮件列表存档,开发人员说" CRunLoopStop()如果使用run方法启动循环,就不要使用NSRunLoop".我可以理解为什么它是这样的 - 你通常将初始化器和终结器配对来自同一组函数.

如何在NSRunLoop没有"诉诸CF" 的情况下停止?我没有看到stop方法NSRunLoop.文档说你可以通过三种方式停止运行循环:

  1. 配置运行循环以使用超时值运行
  2. 告诉运行循环停止使用 CFRunLoopStop()
  3. 删除所有输入源,但这是一种不可靠的方法来停止运行循环,因为你永远无法知道什么困在你背后的运行循环中

好吧,我已经尝试过2.并且有一种"丑陋"的感觉,因为你必须深入研究CF. 3.不可能 - 我不喜欢非确定性代码.

这给我们留下了1.如果我理解正确的文档,你不能"添加"超时已经存在的运行循环.您只能在超时时运行新的运行循环.如果我运行一个新的运行循环,它将无法解决我的问题,因为它只会创建一个嵌套的运行循环.我仍然会回到原来的那个,同样我想停止......对吧?我可能误解了这个.另外,我不想使用超时值运行循环.如果我这样做,我将不得不在刻录CPU周期(低超时值)和响应性(高超时值)之间进行权衡.

这是我现在的设置(伪代码):

Communicator.h

@interface Communicator : NSObject {
    NSThread* commThread;
}

-(void) start;
-(void) stop;
@end
Run Code Online (Sandbox Code Playgroud)

Communicator.m

@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end

@implementation Communicator
-(void) start {
    thread = [[NSThread alloc] initWithTarget:self 
                                     selector:@selector(threadLoop:)
                                       object:nil];
    [thread start];
}

-(void) stop …
Run Code Online (Sandbox Code Playgroud)

macos core-foundation foundation cfrunloop nsrunloop

15
推荐指数
1
解决办法
8001
查看次数

如何将选择器或块发送到NSRunLoop来执行?

我需要保证同一个线程在任意时间执行各种操作.首先,线程需要初始化一个库,然后我希望线程休眠直到需要完成工作,并且在用户输入时,我需要能够传递选择器或块来执行.

如何在初始化后设置NSRunLoop进入睡眠状态?之后,如何通知运行循环唤醒并执行某些操作?

我已经尝试过阅读iOS的线程编程指南,但是我想避免将类设置为自定义输入类并使用更轻量级的东西 performSelector:onThread:

我可以设置一个计时器从现在开始永远开火,所以运行循环不会结束吗?

这基本上是我想要的伪代码:

// Initialization Code...

do {
    sleepUntilSignaled();
    doWorkSentToThisThread();
while (!done);
Run Code Online (Sandbox Code Playgroud)

我把工作发送到哪里作为performSelector:onThread:消息.如果我可以将运行循环发送到像下面这样的块会更好:^{[someObj message]; [otherObj otherMsg];}但是我很高兴,performSelector因为我很确定没有太多额外的编码就可以实现.

谢谢!

iphone objective-c nsrunloop ios4 ios

14
推荐指数
1
解决办法
4654
查看次数

当应用程序在单独的线程中在iOS中处于活动状态时,定期从服务器轮询数据的最佳方法是什么?

我需要在iOS应用程序中定期轮询来自服务器的数据.我需要在一个线程中每隔10秒执行一次,以保持UI可用.当用户登录时,将触发此函数.我正在考虑使用NSRunLoopwith NSTimer来实现此功能,并且可能用于AFNetworking获取JSON数据.

这是正确的方法吗?应该使用GCD吗?

iphone nsrunloop ios

12
推荐指数
1
解决办法
6406
查看次数

如何从iPhone应用程序中删除UIApplicationMain?

我正试图将游戏库移植到iPhone上.与SDL不同,此库不完全控制main()函数,它通过快速返回的函数与您自己的代码进行通信.所以,例如,明显的伪代码:

int main() {
  library_init();
  // game init code here
  while(we_have_not_quit_the_game) {
    library_message_loop();
    library_init_render();
    // render stuff
    library_end_render();
    // update game state
  }
  library_shutdown();
}
Run Code Online (Sandbox Code Playgroud)

iPhone使这很困难,因为它要求你调用一个永不返回的UIApplicationMain函数.在library_init();之后我根本无法回到用户代码.

我不相信它是必要的 - 有NSRunLoop可以用来处理这些事件.然而,我不知道UIApplicationMain是否做了其他重要的事情.(请注意,我没有计划使用.nib文件,这是我发现UIApplicationMain唯一的另一件事.)

我有三个我能想到的真实想法,但它们都是一项重大的实施工作,所以我想知道是否有人有这方面的经验,然后我会花一天时间尝试注定的想法.

  • 在Init中,生成一个新线程,在该线程中运行UIApplicationMain.要么跨线程(ugh)传递所有事件,要么只是将UIApplicationMain线程置于休眠状态并在主线程中使用CFRunLoop.我听说UIApplicationMain不喜欢在不同的线程中运行.
  • 完全忽略UIApplicationMain,只需使用NSRunLoop.我是否会错过重要的iPhone设置?谁知道!
  • 做一些可怕的事情,使用longjmp()在安装后跳出UIApplicationMain代码,祈祷它在拆解过程中没有做任何重要的事情.

建议?

iphone uiapplication nsrunloop

11
推荐指数
2
解决办法
2865
查看次数

iOS5在runMode:beforeDate期间崩溃:

我的应用程序与iOS5 b7和GM版本的兼容性存在问题.

问题出现在下一行代码中:

do {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
Run Code Online (Sandbox Code Playgroud)

EXC_BAD_ACCESS在一些迭代之后,应用程序与信号崩溃.

传递的迭代次数是随机的(从2到7).

在iOS4和iOS3上一切都运行良好.

Apple的示例中出现了同样的问题:XMLPerformance Sample.

你怎么看待这件事?

10月12日我的应用程序的数千名用户将升级到iOS5,我不希望我的应用程序在AppStore中出现如此奇怪的错误.

exc-bad-access objective-c nsrunloop ios ios5

10
推荐指数
1
解决办法
5395
查看次数

PerformSelector延迟不在后台模式下运行 - iPhone

我有一个voip应用程序,它也在后台运行.当我在后台时,我正在从主线程调用:(在我诊断网络丢失的情况下建立网络连接).

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

但是,只有当我的应用程序返回到前台时才会执行选择器.我应该做些什么来让选择器在后台执行吗?

谢谢

编辑:

-(void) reconectInBackgroundAfterDelay:(NSTimeInterval) dealy
{
    NSLog(@"reconectInBackgroundAfterDelay");
    UIApplication*   app = [UIApplication sharedApplication];

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [self performSelector :@selector(Reconnect:) withObject:nil afterDelay:dealy];

        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}
Run Code Online (Sandbox Code Playgroud)

我添加了这个代码,但仍然没有在提供的延迟后调用"重新连接"方法.我已经在后台调用"reconectInBackgroundAfterDelay"方法.

还有其他建议吗?

编辑2 找到解决方案.见下文

iphone objective-c nstimer nsrunloop ios4

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

将当前线程NSRunLoop设置为以某种模式运行的正确方法是什么,直到我决定停止它为止?

我想模仿UIScrollView行为,当你拖动scrollView时当前线程RunLoop模式更改为UITrackingRunLoopMode,并在停止拖动时返回NSDefaultRunLoopMode.

我想用我自己的类来做,但是拖着视图......现在我正在使用这段代码

while (_draggingView && [[NSRunLoop currentRunLoop] runMode:UITrackingRunLoopMode beforeDate:[NSDate distantFuture]]);
Run Code Online (Sandbox Code Playgroud)

当我停止拖动时,_draggingView更改为nil,因此我停止在该模式下循环.这样做有更优雅/更好的方式吗?

UIScrollView是如何做到的?输入源?

谢谢

uiscrollview nsrunloop ios

10
推荐指数
1
解决办法
1831
查看次数

如何在NSThread中等待,直到iOS发生某些事件?

在iOS中发生某些事件之前,如何在NSThread内等待?

例如,我们创建了一个NSThread并启动了一个线程循环.在线程循环内部,有条件检查消息队列是否有任何消息.如果有消息,那么它将调用相应的方法来执行某些操作,否则它应该等到消息队列填充新消息.

是否有任何API或方法可用于等待某些事件发生?

For Example 

NSThread *thread = [NSThread alloc]....@selector(threadLoop)

- (void)threadLoop
{
   // Expecting some API or method that wait until some messages pushed into the message queue
   if (...) {

   }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助应该被赞赏.

iphone objective-c nsthread nsrunloop ios

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

如何停止计时器触发的runloop?

如果我设置这样的runloop:

NSRunloop* loop = [NSRunloop currentRunLoop];
[runLoop addTimer:anyTimer forMode:NSDefaultRunLoopMode];
Run Code Online (Sandbox Code Playgroud)

我可以再次阻止它吗?或者是忽略我用来触发进一步行动的通知的唯一方法?

好的,我举一个问题的例子:

-(void)blinkeffekt:(double)pollingTime{

NSRunLoop* runLoop = [NSRunLoop currentRunLoop];

if (pollingTime != 0) {
    NSTimeInterval interval =(double)pollingTime / 1000;
    NSTimer timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(polling) userInfo:nil repeats:YES];
    [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}
else {

    [timer invalidate];
}
Run Code Online (Sandbox Code Playgroud)

}

当然,这里有几个错误 - 毫无疑问.但我想,它显示了我的问题.直到现在,这个答案还无法解决.

我需要运行一个计时器并在以后停止它.理想情况下,在课堂上的另一个功能.但后来我不能访问"定时器"了,并runloop犯规让搞清楚,如果这样的"消息"是可用的.如果我为每个函数调用注册一个新的计时器,它将是非常无效的.

iphone timer objective-c nsrunloop

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

正在调用 - [NSRunLoop runUntilDate:]一个好主意?

打电话通常是个好主意-[NSRunLoop runUntilDate:]吗?它似乎没有任何问题,但它让我很紧张,告诉运行循环从运行循环内运行.

更多信息:

我现在有一个从REST服务获取数据的项目.需要获得的一个关键信息是具有有效数据的日期范围.它是只需要一次得到的数据非常小一点,所以我决定来处理它的最好办法是让物业下载数据,如果局部变量nil.我正在使用ASIHTTPRequest和一个ASINetworkQueue,所以默认情况下一切都是异步的,为了使这个工作,这个属性在下载和处理数据之前不能返回.这是我的代码的大纲,变量的名称已被更改以保护无辜:

__block BOOL isWorking = YES;
__block ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:/*actual URL*/] autorelease];
[request setCompletionBlock:^{
    // set local variable
    isWorking = NO;
}];
[request setFailedBlock:^{
    // show alert to user
    isWorking = NO;
}];
[queue addOperation:request];

while (isWorking) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
Run Code Online (Sandbox Code Playgroud)

再次,这似乎工作正常.使用这种方法有任何潜在的问题吗?

iphone asihttprequest nsrunloop ipad ios

9
推荐指数
1
解决办法
6976
查看次数