2013-05-10 119 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