HIDManager Wierd CFRunLoop终止 [英] HIDManager Wierd CFRunLoop Termination
问题描述
我已经创建了设备匹配和设备删除回调,并且需要运行CFRunLoop以便在插入和删除设备时调用这些回调.
I've created device matching and device removal callbacks, And need to run CFRunLoop to get those callbacks invoked whenever device plugged in and removed.
但是问题是,DeviceMatching回调需要大量的处理时间,并且取决于要连接的设备,因此我想通过在有限的时间内运行CFRunLoop来检测是否删除了设备,并且发生了设备删除回调
But the problem is, DeviceMatching callback takes a lot of processing time and depends on device to be attached, So I want to detect if device is removed by running the CFRunLoop for a limited time, and With that the device removal callback happens.
但是,它可以工作2次,然后抛出exe_bad_access.
But, It works for 2 times and then it throws exe_bad_access.
IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );
if( matchingCFDictRef ) {
CFRelease( matchingCFDictRef );
}
IOHIDManagerRegisterDeviceMatchingCallback(tIOHIDManagerRef,
Handle_DeviceMatchingCallback,NULL);
IOHIDManagerRegisterDeviceRemovalCallback(tIOHIDManagerRef, Handle_RemovalCallback, NULL);
IOHIDManagerScheduleWithRunLoop(tIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRunLoopRun();
设备添加回调
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
}
设备移除回调:
static void Handle_RemovalCallback( void* inContext,IOReturn inResult,
void* inSender, IOHIDDeviceRef inIOHIDDeviceRef) {
//NOW THIS GET's INVOKED, after keeping in run loop
}
以下是用于生成匹配CFDictRef
Following is the code for generating matchingCFDictRef
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 );
推荐答案
如何生成matchingCFDictRef
?尽管通常的约定会建议IOHIDManager保留或复制它,但有可能不是.我现在尝试将CFRelease
取出,看看是否有改善.
How do you generate matchingCFDictRef
? Though normal conventions would suggest that IOHIDManager should retain or copy it, it's possible that it isn't. I would try taking out the CFRelease
for now and see if that improves things.
CFGetTypeID
中的崩溃表明它正在尝试使用已释放的CF对象.您可以尝试调试以下几项:
The crash in CFGetTypeID
indicates that it is trying to work with a CF object that has been freed. A few things you can do to try to debug which one it is:
- 打开 NSZombie .即使这是一个CF对象,它也可能会起作用(许多CF对象都是免费桥接的,并且仍然可以使用).
- 在调试器中,检查
CFGetType
的参数.请参阅在gdb 获取正确的寄存器,具体取决于您的处理器. (此页面用于ObjC并不重要;您只需要与arg0
有关的全部内容即可.)
- Turn on NSZombie. It might work, even though this is a CF object (many CF objects are toll free bridged and will still work).
- In the debugger, check the parameter to
CFGetType
. See Inspecting Obj-C parameters in gdb for the correct register depending on your processor. (It doesn't matter that this page is for ObjC; you just want the entires related toarg0
.)
这篇关于HIDManager Wierd CFRunLoop终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!