【发布时间】:2012-02-06 23:32:52
【问题描述】:
我已经创建了设备匹配和设备移除回调,并且需要运行 CFRunLoop 以在设备插入和移除时调用这些回调。
但问题是,DeviceMatching 回调需要大量处理时间并且取决于要附加的设备,所以我想通过在有限的时间内运行 CFRunLoop 来检测设备是否被移除,并且设备移除回调发生.
但是,它工作了 2 次,然后它抛出 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
}
以下是生成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 );
【问题讨论】:
-
哪一行产生异常?堆栈是什么?
-
CFRunLoopRun(); (我还在堆栈跟踪中看到 CFRunLoop 调用 CFGetTypeID)
-
堆栈包含第一个代码块的方法,然后是CFRunLoop,然后是CFGetTypeID
标签: objective-c macos device-driver hid