标签: cfrunloop

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
查看次数

Swift命令行程序中的CFRunLoop

我正在使用第三方框架在Swift中编写命令行应用程序(如果我理解正确的代码)依赖于GCD回调来在套接字接收数据时完成某些操作.为了更好地理解框架,我一直在使用框架作者编写的示例Cocoa应用程序来与框架一起使用.

因为示例应用程序是Cocoa应用程序,所以自动处理运行循环.我在示例应用程序(MIT许可证)中包含代码片段,以了解它是如何工作的:

class AppDelegate: NSObject, NSApplicationDelegate {


  var httpd : Connect!

  func startServer() {
    httpd = Connect()
      .onLog {
        [weak self] in // unowned makes this crash
        self!.log($0)
      }
      .useQueue(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
Run Code Online (Sandbox Code Playgroud)

...

     httpd.listen(1337)
}
Run Code Online (Sandbox Code Playgroud)

...

 func applicationDidFinishLaunching(aNotification: NSNotification?) {
    startServer()

   ...

    }
  }
Run Code Online (Sandbox Code Playgroud)

我想修改示例应用程序以从命令行运行.当我将startServer()函数放入命令行应用程序时,它会运行,但是套接字在打开后立即关闭,并且程序以退出代码0完成执行.这是预期的行为,因为没有运行循环在Xcode命令行项目中,因此程序不知道等待套接字接收数据.

我相信让套接字保持打开的正确方法是连续运行程序将主线程放在CFRunLoop中.我查看了Apple的文档,除了基本的API参考,Swift中没有任何线程.我查看了第三方资源,但它们都涉及iOS和Cocoa应用程序中的备用线程.如何正确实现主线程的CFRunLoop?

cfrunloop grand-central-dispatch swift

9
推荐指数
2
解决办法
5265
查看次数

停止NSRunLoop

我在一个线程中有一个连接,所以我将它添加到运行循环中以获取所有数据:

  [[NSRunLoop currentRunLoop] run];
  [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
Run Code Online (Sandbox Code Playgroud)

但我找不到任何阻止它的方法

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    if([NSRunLoop currentRunLoop]){
        [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
    }
    [connection cancel];
}
Run Code Online (Sandbox Code Playgroud)

我怎么能阻止这个循环呢?

cocoa cocoa-touch nsurlconnection cfrunloop nsrunloop

8
推荐指数
1
解决办法
6377
查看次数

从另一个线程调用CFRunLoopStop是否安全?

我的(主要是POSIX)应用程序的Mac构建产生一个子线程,它调用CFRunLoopRun()来执行事件循环(从MacOS获取网络配置更改事件).

当打包并离开时,主线程在子线程的运行循环上调用CFRunLoopStop(),此时CFRunLoopRun()在子线程中返回,子线程退出,主线程(这是阻止等待子线程退出)可以继续.

这似乎有效,但我的问题是:这是一种安全/推荐的方式吗?特别是,从另一个线程调用CFRunLoopStop()容易导致竞争条件?据我所知,Apple的文档对此主题保持沉默.

如果从主线程调用CFRunLoopStop()不是解决方案,那么什么是好的解决方案?我知道我可以让子线程调用CFRunLoopRunInMode()并经常唤醒以检查布尔值或其他东西,但我宁愿不让子线程做任何轮询,如果我可以避免它.

c c++ multithreading macos-carbon cfrunloop

6
推荐指数
2
解决办法
3187
查看次数

为什么在音频队列播放代码中调用CFRunLoopRunInMode()?

我正在关注iOS"音频队列编程指南 - 播放音频".在指南的末尾,可以CFRunLoopRunInMode()在步骤Start和Run a Audio Queue中调用:

do {                                               // 5
    CFRunLoopRunInMode (                           // 6
        kCFRunLoopDefaultMode,                     // 7
        0.25,                                      // 8
        false                                      // 9
    );
} while (aqData.mIsRunning);
//...
Run Code Online (Sandbox Code Playgroud)

第6行的文档说:"CFRunLoopRunInMode函数运行包含音频队列线程的运行循环." 但是,当我的方法返回时,是不是执行了运行循环?上面的代码是在我的应用程序中按下播放按钮时由主线程执行的.

现在我很难理解这些调用CFRunLoopRunInMode()有什么好处,因为它们的缺点是我的播放按钮没有正确更新(它看起来整个音频播放的时候按下了)并且没有正面效果,即如果我从我的代码中删除do-while-loop以及调用CFRunLoopRunInMode()而直接从此方法返回,则音频也可以很好地播放.那么这就指出了显而易见的解决方案,只需将这些调用删除,因为这不会产生问题.有人可以解释为什么苹果公司在使用iOS中的音频队列进行音频播放的官方指南中包含此代码吗?

编辑:

我只是在Mac OS X中看到,存在与iOS相同的音频队列API,iOS指南似乎是Mac OS指南的复制粘贴复制品.这让我怀疑那些对运行循环的调用仅在Mac OS中需要而在iOS中不再需要,例如因为否则Mac OS应用程序会退出或类似的东西.有人可以验证这个或排除它吗?

playback audioqueueservices cfrunloop ios

6
推荐指数
1
解决办法
2849
查看次数

在 swift 2 中使用 UnsafeMutablePointer 和 CFRunLoopObserverContext

我有以下代码

private func addRunLoopObserverForSaving() {
    var _self = self

    withUnsafeMutablePointer(&_self) { (pSelf) -> Void in
        var observerContext = CFRunLoopObserverContext(
            version: 0,
            info: pSelf,
            retain: nil,
            release: nil,
            copyDescription: nil)

        withUnsafeMutablePointer(&observerContext, { (pObserverContext) -> Void in

            let observer = CFRunLoopObserverCreate(
                kCFAllocatorDefault,
                CFRunLoopActivity.BeforeTimers.rawValue,
                true,
                0,
                { (observer, activity, context) -> Void in
                    guard context != nil else { return }

                    let pObserverContext = UnsafeMutablePointer<CFRunLoopObserverContext>(context)
                    let pGraphsModel = UnsafeMutablePointer<GraphsModel>(pObserverContext.memory.info)

                    let z = pGraphsModel.memory
                    ...
                },
                pObserverContext
            )

            CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode)
        })
    }
} …
Run Code Online (Sandbox Code Playgroud)

cfrunloop swift xcode7

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

NSRunLoop正在消耗大量的CPU和内存

我有一个无限循环驱动我的工作线程.

-(void) myThread
{
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];   
    while(![myThread isCancelled])
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:600]];
    }
    [pool release];
}
Run Code Online (Sandbox Code Playgroud)

但有时候这些线程占用了很多CPU(50-100%)和内存(1.5GB).当我在这种状态下对应用程序进行采样时,我得到了以下跟踪

    453 +[NSDate dateWithTimeIntervalSinceNow:]
          309 -[__NSPlaceholderDate initWithTimeIntervalSinceReferenceDate:]
            295 CFDateCreate
              268 _CFRuntimeCreateInstance
                115 malloc_zone_malloc
                  64 __spin_lock
                    64 __spin_lock
                  43 szone_malloc
                    22 tiny_malloc_from_free_list
                      22 tiny_malloc_from_free_list
                    19 szone_malloc
                    2 spin_unlock
                      2 spin_unlock
                  4 malloc_zone_malloc
                  3 dyld_stub__spin_unlock
                    3 dyld_stub__spin_unlock
                  1 dyld_stub__spin_lock
                    1 dyld_stub__spin_lock
                99 __bzero
                  99 __bzero
                29 malloc_size
                  23 szone_size
                    23 szone_size
                  6 malloc_size
                13 CFAllocatorAllocate
                  13 CFAllocatorAllocate
                12 _CFRuntimeCreateInstance
              20 CFDateCreate
              4 CFDateGetTypeID …
Run Code Online (Sandbox Code Playgroud)

cocoa objective-c cfrunloop nsrunloop

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

在 Swift 中使用 IOPSNotificationCreateRunLoopSource 创建 CFRunLoopSourceRef

我正在尝试订阅 macOS 上电源状态的更改。我发现有一种使用 IOKit 的方法,尽管它有点复杂。我需要#import <IOKit/ps/IOPowerSources.h>在 ObjC 桥接标头中使用它来导入它。然后我可以访问函数 IOPSNotificationCreateRunLoopSource,其签名为:

IOPSNotificationCreateRunLoopSource(_ callback: IOPowerSourceCallbackType!, _ context: UnsafeMutablePointer<Void>!) -> Unmanaged<CFRunLoopSource>!
Run Code Online (Sandbox Code Playgroud)

我从Callback method to Apple run Loop的答案中得到了一些帮助,但仍然无法IOPowerSourceCallbackType在 Swift 中创建类型的函数。编译此程序时缺少什么?

types callback iokit cfrunloop swift

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

iOS:CFRunLoopRun()函数混乱

我已经阅读了CFRunLoop,但仍然有点困惑.我来了一段代码,我想为自己澄清一下:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:url]]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];
[[NSURLConnection alloc]initWithRequest:request delegate:self];

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

所以,假设这一切都在主线程上被调用,它会阻塞主线程吗?或者它会通过CFRunLoopRun()函数调用生成一个新线程吗?

谢谢!

multithreading objective-c cfrunloop ios

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

尝试编译调用本机代码的类时,Mono编译器崩溃

我有以下类使用Mono(在mac中)将一些运行循环调用从本机代码映射到C#,并且编译器不起作用,它在尝试编译时一直崩溃.我已将其删除到仅包含此类的单独项目,但它仍然已损坏,因此看起来问题是具体使用此代码.

有没有人见过这样的东西?

using System;
using System.Threading;

namespace Integration.Mac
{

    public class CommonRunLoop
    {

        static IntPtr runLoopReference;

        public static IntPtr CommonRunLoopReference {
            get {
                return runLoopReference;
            }
        }

        static CommonRunLoop() {

            AutoResetEvent lockObj = new AutoResetEvent (true);

            Thread runLoop = new Thread (delegate() {
                runLoopReference = CFRunLoopGetCurrent ();
                lockObj.Set ();
                CFRunLoopRun ();
            });

            runLoop.IsBackground = true;
            runLoop.Name = "Common-Sync-Run-Loop";
            lockObj.WaitOne();
        }

        [DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
        extern static IntPtr CFRunLoopGetCurrent ();

        [DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
        extern static IntPtr CFRunLoopGetMain ();

        [DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
        extern static …
Run Code Online (Sandbox Code Playgroud)

c# macos mono interop cfrunloop

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