2013-05-10 54 views
2

我正在写一个方法来接收USB设备插入/拔出插头时的操作系统通知。我曾经在这个问题上从Mac OS通知USB设备添加/删除

How to know when a HID USB/Bluetooth device is connected in Cocoa?意见。

这就是我:

io_iterator_t portIterator; 

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class 
long vendorID = usbVendorId; 
long productID = usbProductID; 

// Create a CFNumber for the idVendor and set the value in the dictionary 
CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorID); 
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); 
CFRelease(numberRef); 

// Create a CFNumber for the idProduct and set the value in the dictionary 
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &productID); 
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); 
CFRelease(numberRef); 
numberRef = NULL; 

mach_port_t    masterPort; 
IOMasterPort(MACH_PORT_NULL, &masterPort); 

// Set up notification port and add it to the current run loop for addition notifications. 
IONotificationPortRef notificationPort = IONotificationPortCreate(masterPort); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), 
        IONotificationPortGetRunLoopSource(notificationPort), 
        kCFRunLoopDefaultMode); 


// Register for notifications when a serial port is added to the system. 
// Retain dictionary first because all IOServiceMatching calls consume dictionary. 
CFRetain(matchingDict); 
kern_return_t result = IOServiceAddMatchingNotification(notificationPort, 
                 kIOMatchedNotification, 
                 matchingDict, 
                 usbDeviceAdded, 
                 nil,   
                 &portIterator); 
// Run out the iterator or notifications won't start. 
while (IOIteratorNext(portIterator)) {}; 


// Also Set up notification port and add it to the current run loop removal notifications. 
IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), 
        IONotificationPortGetRunLoopSource(terminationNotificationPort), 
        kCFRunLoopDefaultMode); 

// Register for notifications when a serial port is added to the system. 
// Retain dictionary first because all IOServiceMatching calls consume dictionary. 
CFRetain(matchingDict); 
kern_return_t result1 = IOServiceAddMatchingNotification(terminationNotificationPort, 
              kIOTerminatedNotification, 
              matchingDict, 
              usbDeviceRemoved, 
              this,   
              &portIterator); 

// Run out the iterator or notifications won't start. 
while (IOIteratorNext(portIterator)) {}; 
CFRetain(matchingDict); 
我有同样的问题,原来的海报有

。我收到通知,但只有一次删除/添加。如果我尝试添加/删除不同的设备,则无关紧要,我只会收到一条通知。之后,我只是没有得到通知。

有人可以帮我找出为什么会发生这种情况。谢谢!

回答

1

IOKit device adding/removal notifications - only fire once?

这是我发现我的答案,但它不是很容易被发现。

事实证明,即在添加/移除的设备的接收的通知的方法中需要一定运行端口迭代器。

因此,在回调方法中,需要像这样的语句。

while(IOIteratorNext(portIterator)){};

或者做一些其他的事情,只需运行迭代器即可。我被强烈地指出,这并不是在任何地方指定的。

+0

是的,这是最正确的。该行为在[IOServiceAddMatchingNotification]的* notification *参数中描述(https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOKitLib_header_reference/Reference/reference.html#//apple_ref/doc/) c_ref/IOServiceAddMatchingNotification)函数。注意,即使你不需要它,你也必须释放'IOIteratorNext()'返回的对象,所以'while'循环实际上是不正确的。 – pmdj 2013-05-12 14:21:08