标签: nsrunloop

在iPhone上使用AsyncSocket和辅助线程

我在iPhone上使用AsyncSocket与服务器通信.AsyncSocket基于运行循环,但我的应用程序基于线程.这意味着,我启动一个新线程来写入数据,并等待直到在同一个线程上收到响应.但我不能直接从另一个线程调用AsyncSocket的方法,我必须使用:

[self performSelectorOnMainThread:@selector(writeSomeData:) withObject:dataToWrite waitUntilDone:YES];
Run Code Online (Sandbox Code Playgroud)

它确实有效,但我无法通过这种方式调用我的方法"writeSomeData:",因为performSelectorOnMainThread不返回任何内容.

方法writeSomeData:做这样的事情:

-(NSData *)writeData:(NSData *)dataToWrite {
    dataReceived = nil; // AsyncSocket writes data to this variable
    [asyncSocket writeData:dataToWrite withTimeout:-1 tag:0];
    [asyncSocket readDataToData:[@"<EOF" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    int counter = 0;
    while (dataReceived == nil && counter < 5) {
        // runLoop is [NSRunLoop currentRunloop]
        [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
        ++counter;
    }

    return [dataReceived copy];
}
Run Code Online (Sandbox Code Playgroud)

我可以通过访问类变量"dataReceived"获得响应,但此时内容已更改.

任何人都可以告诉我如何在不同的线程上使用AsyncSocket(或者一般来说,如何处理基于运行循环的类),这样如果我调用该类的方法,它会一直阻塞,直到执行该方法并收到响应?

谢谢.

iphone cocoa-touch asyncsocket nsthread nsrunloop

5
推荐指数
1
解决办法
1326
查看次数

如何防止iOS 5中的用户界面操作延迟或中断NSTimer

如何防止用户滚动表格导致NSTimer延迟?

我找到了答案:

我有一个计时器,重复约8或9次,间隔为0.4到0.8秒.我不需要太多的精度,但如果用户滚动表,计时器将停止工作,直到表完成滚动(这可能是几秒钟等待!).我以为我需要后台线程,但是后台线程上的定时器实现起来有些复杂.

我的问题的答案非常简单容易.我只需要在调用计时器后添加一行:

//////////// start the timer

self.playingTimer = [NSTimer scheduledTimerWithTimeInterval:tempo target:self selector:@selector(playSoundFromArray:) userInfo:nil repeats:YES];

//////////// the magic line:

[[NSRunLoop currentRunLoop] addTimer:self.playingTimer forMode:UITrackingRunLoopMode];
Run Code Online (Sandbox Code Playgroud)

现在我可以根据需要滚动表格,我的计时器工作正常!

现在我需要再研究一下NSRunLoop ......

nsrunloop ios ios5

5
推荐指数
1
解决办法
411
查看次数

NSRunLoop runMode并不总是处理dispatch_async

我试图更好地了解队列及其工作原理。这个片段是为了测试他们的行为:

- (void)dispatchQueueTest
{
    NSLog( @"Begin test on %@ thread", [NSThread isMainThread] ? @"main" : @"other" );
    dispatch_semaphore_t s = dispatch_semaphore_create(0);

    dispatch_async( dispatch_get_main_queue(), ^{
        NSLog( @"Signalling semaphore" );
        dispatch_semaphore_signal(s);
    });

    NSLog( @"Waiting for worker" );
    while( dispatch_semaphore_wait( s, DISPATCH_TIME_NOW ) ) {
        NSDate* timeout = [NSDate dateWithTimeIntervalSinceNow:10.f];
        // Process events on the run loop
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeout];
    }
    dispatch_release(s);
    NSLog( @"All sync'd up" );
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,它会在日志中生成以下内容:

Begin test on main thread
Waiting for worker
Signalling semaphore
All sync'd up …
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch nsrunloop dispatch-async

5
推荐指数
1
解决办法
1413
查看次数

Objective-C:主线程及其runloop中的代码如何交互?

主线程及其runloop中的代码如何交互?例如,主线程中的所有代码是否必须运行,直到它在进入runloop之前处于空闲状态?或者runloop在主线程中执行代码的过程中检查其源代码?runloop源是否有可能阻止主线程代码执行(因为它在同一个线程上运行)?

我试图理解主要线程代码如何适应在宏观方案中的runloop图片(反之亦然).

这是一个runloop与我们的代码一起的样子:

主线程:

  1. runloop以特定间隔运行
  2. runloop完成运行,我们的代码运行
  3. 我们的代码运行完毕,转到(1)(如果我们的代码运行得太久以至于runloop没有机会运行怎么办?)

multithreading objective-c nsrunloop ios

5
推荐指数
1
解决办法
2221
查看次数

是否应将NSTimer添加到runloop中以执行

我没有明确地将定时器添加到runloop并且它工作得很好.有一天,当我阅读一些文章时NSRunLoop,它说最好将一个NSTimer实例添加到runloop实例中来执行.我只是想知道如果我不这样做会有什么危害吗?

nstimer nsrunloop ios

5
推荐指数
1
解决办法
1400
查看次数

Swift 中的线程间通信?

我的目标是使用 Swift 解析大型 XML 文件 (20 GB)。NSXMLParser 和与 Swift 对象的桥接存在一些性能问题,因此我正在考虑多线程。具体有以下划分:

  1. 主线程-解析数据
  2. 工作线程 - 将 ObjC 类型转换为 Swift 类型并发送到 1。将 ObjC NSDictionary 转换为 [String: String] 是最大的瓶颈。这也是分离到多线程的主要原因。
  3. 工作线程 - 将 XML 解析为 ObjC 类型 - 并发送到 2. NSXMLParser 是一个推送解析器,一旦开始解析,就无法暂停它。

应按顺序解析数据,因此应保持输入顺序。我的想法是在 1 和 2 上运行 NSRunLoop,允许并行处理而不会阻塞。根据Apple的文档,线程之间的通信可以通过调用来实现performSelector:onThread:withObject:waitUntilDone:。然而这个符号在 Swift 中不可用。

我认为 GCD 不适合作为解决方案。两个工作线程都应该是长时间运行的进程,新工作以随机间隔进入。

如何使用 Swift 实现上述目标(例如,多线程上的 NSRunLoops)?

multithreading nsrunloop swift

5
推荐指数
1
解决办法
953
查看次数

当应用程序背景时,NSTimer的行为是什么?

我知道当你为应用程序提供后台时,计时器会停止运行.但是,当你从后台回来时的行为是什么?计时器是否保持其原始状态fireDate

我遇到了一个问题,在从背景返回时,NSTimer设置为在十分钟内启动,有时我applicationWillEnterForeground:甚至会在调用之前立即启动计时器.当它没有触发并且applicationWillEnterForeground:被调用时,我有一些逻辑可以通过比较计时器fireDate和当前日期来检查是否已经过了10分钟,但是,即使已经过了10分钟,它总是给我一个值从当前日期开始约525秒.

我的理论如下:

  • 一个NSTimer在未来从背景后面会触发计时器,只要你还没有比原先计划更多的错过了预定时间.(在这种情况下,我们将计时器安排为10分钟,只要您在后台进行10-20分钟,它将在重新进入应用程序时触发.)

  • 如果超过该值,则不会触发,而是在您返回时在将来的同一时间段内安排另一个计时器.(AKA如果您在10分钟的计时器中已经在后台工作了20多分钟,当您回来时,它会在您返回应用程序之后将计时器安排在10分钟内.)

有没有人有关于这种行为的任何文件?我的理论完全基于观察,关于当背景要么严重缺乏或者我无法找到它时会发生什么的文档.

nstimer nsrunloop ios

5
推荐指数
1
解决办法
660
查看次数

RunLoop vs DispatchQueue作为调度程序

使用新的Combine框架时,您可以指定用于从发布服务器接收元素的调度程序。

在将发布者分配给UI元素时RunLoop.mainDispatchQueue.main在这种情况下,两者之间有很大区别吗?第一个返回主线程的运行循环,第二个返回与主线程关联的队列。

grand-central-dispatch nsrunloop swift combine

5
推荐指数
3
解决办法
260
查看次数

从计时器停止NSRunLoop

我已经制作了一个带有计时器的RunLoop,它可以更新显示倒计时的标签.倒计时到零时我需要RunLoop停止,对于计时器正常结束的情况,我可以使用runUntilDate,日期是当前日期+倒计时时间.问题是当用户在按钮完成之前取消倒计时.我不知道如何告诉RunLoop停止取消按钮操作.这是RunLoop的代码:

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                            [self methodSignatureForSelector:@selector(updateCountdownLabel:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(updateCountdownLabel:)];
[[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:1 invocation:invocation repeats:YES] forMode:NSRunLoopCommonModes];
Run Code Online (Sandbox Code Playgroud)

该方法只是告诉标签在每个循环中减少1.

我可以告诉取消按钮将标签更改为零,并让运行循环选择器检查值是否为零,但RunLoop自己的选择器是否可以告诉它停止?

cancelPerformSelector:target:argument:

cancelPerformSelectorsWithTarget:
Run Code Online (Sandbox Code Playgroud)

这些是我发现的最接近但它们似乎不是从RunLoops自己的选择器内部工作,或者至少不是我尝试过它们的任何方式.

基本上我需要让按钮告诉RunLoop停止,或以某种方式阻止RunLoop从它自己的选择器.

谢谢.

cocoa timer nstimer nsrunloop runloop

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

Swift 3 Linux with Perfect:在runLoop中添加一个带间隔的预定计时器

我正在尝试使用该Perfect在我的Ubuntu(Ubuntu 15.10 wily,Swift swift-3.0.1-RELEASE)上使用Swift创建一个应用程序.

我希望每X秒都有一个函数.为此,我正在使用模块TimerFoundation:

class MyTimer {
    init() {
        var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MyTimer.onTimer(timer:)), userInfo: nil, repeats: true)
    }
    @objc func onTimer(timer: Timer) {
        print("MyTimer.onTimer")
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管使用此代码找到了几个解决方案,但编译失败了:

$> swift build
Compile Swift Module 'my-app' (7 sources)
/home/.../Sources/MyTimer.swift:8:16: error: method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C
    @objc func onTimer(timer: Timer) {
Run Code Online (Sandbox Code Playgroud)

如果我正在扩展我的类NSObject或者如果我删除了参数,则会出现另一个编译错误timer:

$> …
Run Code Online (Sandbox Code Playgroud)

timer nsrunloop swift perfect swift3

4
推荐指数
1
解决办法
896
查看次数