首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HIDManager Wierd CFRunLoop终端

HIDManager Wierd CFRunLoop终端
EN

Stack Overflow用户
提问于 2012-02-07 07:32:52
回答 2查看 624关注 0票数 1

我已经创建了设备匹配和设备移除回调,并且需要运行CFRunLoop来在设备插入和移除时调用这些回调。

但问题是,DeviceMatching回调需要大量的处理时间,并且依赖于要附加的设备,所以我希望通过运行CFRunLoop一段有限的时间来检测设备是否被移除,并且设备移除回调也随之发生。

但是,它工作了2次,然后抛出了exe_bad_access。

代码语言:javascript
复制
  IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );
  if( matchingCFDictRef ) {
        CFRelease( matchingCFDictRef );
  }
  IOHIDManagerRegisterDeviceMatchingCallback(tIOHIDManagerRef,
                                                 Handle_DeviceMatchingCallback,NULL);
  IOHIDManagerRegisterDeviceRemovalCallback(tIOHIDManagerRef, Handle_RemovalCallback, NULL);

  IOHIDManagerScheduleWithRunLoop(tIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
      CFRunLoopRun();

设备添加回调

代码语言:javascript
复制
static void Handle_DeviceMatchingCallback(void* inContext, IOReturn inResult, 
                             void* inSender, IOHIDDeviceRef  inIOHIDDeviceRef) {
      //DO SOME HEAVY PROCESSING

      //NOW WE NEED TO CHECK IF DEVICE IS STILL CONNECTED
     [[NSRunLoop currentRunLoop]  runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];

      //DO POST PROCESSING

}

设备移除回调:

代码语言:javascript
复制
static void Handle_RemovalCallback( void* inContext,IOReturn  inResult,
                        void*  inSender, IOHIDDeviceRef inIOHIDDeviceRef) {
     //NOW THIS GET's INVOKED, after keeping in run loop

}

以下是生成matchingCFDictRef的代码

代码语言:javascript
复制
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );
EN

回答 2

Stack Overflow用户

发布于 2012-02-07 23:49:59

如何生成matchingCFDictRef?虽然正常的约定建议IOHIDManager应该保留或复制它,但也有可能不是这样,我现在试着去掉CFRelease,看看这样做是否会有所改善。

CFGetTypeID中的崩溃表明它正在尝试使用已释放的CF对象。您可以做一些事情来尝试调试它是哪一个:

  • 打开NSZombie。它可能会工作,即使这是一个CF对象(许多CF对象是免费桥接的,并且仍然可以工作)。
  • 在调试器中,检查参数为CFGetType。请参阅Inspecting Obj-C parameters in gdb,了解取决于您的处理器的正确寄存器。(这个页面是用于ObjC的并不重要;您只需要与arg0.)

相关的所有内容

票数 1
EN

Stack Overflow用户

发布于 2012-02-08 01:32:16

以下是生成matchingCFDictRef的代码

代码语言:javascript
复制
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFNumberRef vendorIDCFNumRef  = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendorId );
    CFNumberRef productIDCFNumRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &productId );

    CFDictionarySetValue( matchDict, CFSTR( kIOHIDVendorIDKey  ), vendorIDCFNumRef );
    CFDictionarySetValue( matchDict, CFSTR( kIOHIDProductIDKey ), productIDCFNumRef );

    CFRelease( vendorIDCFNumRef );
    CFRelease( productIDCFNumRef );

现在,我看到了从CFRunLoop调用的不同堆栈跟踪,尽管我仍然在符号中看到了GetTypeID

代码语言:javascript
复制
0x00007fff8534407a  <+0023>  jne    0x7fff8534409f <IOHIDDeviceScheduleWithRunLoop+60>
0x00007fff8534407c  <+0025>  mov    0x18(%rdi),%rdi
0x00007fff85344080  <+0029>  mov    (%rdi),%rax
0x00007fff85344083  <+0032>  lea    0x58(%r12),%rsi
0x00007fff85344088  <+0037>  callq  *0x40(%rax)
0x00007fff8534408b  <+0040>  test   %eax,%eax
0x00007fff8534408d  <+0042>  jne    0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff85344093  <+0048>  cmpq   $0x0,0x58(%r12)
0x00007fff85344099  <+0054>  je     0x7fff85344148 <IOHIDDeviceScheduleWithRunLoop+229>
0x00007fff8534409f  <+0060>  mov    0x58(%r12),%rdi
0x00007fff853440a4  <+0065>  callq  0x7fff85368f36 <dyld_stub_CFGetTypeID>
0x00007fff853440a9  <+0070>  mov    %rax,%rbx
0x00007fff853440ac  <+0073>  callq  0x7fff85369008 <dyld_stub_CFRunLoopSourceGetTypeID>
0x00007fff853440b1  <+0078>  cmp    %rax,%rbx
0x00007fff853440b4  <+0081>  jne    0x7fff853440cc <IOHIDDeviceScheduleWithRunLoop+105>

我看到它在IOHIDDeviceScheduleWithRunLoop的0x00007fff85344080 <+0029> mov (%rdi),%rax处中断(请使用0x00007fff85344080搜索)

在参考文档的帮助下,我看到它是第一个参数,意思是tIOHIDManagerRef,我创建了IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault,kIOHIDOptionsTypeNone );

但是,如何从上面的堆栈跟踪中查看它的地址呢?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9168936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档