2013-06-25 80 views
2

這是我的代碼,當我運行應用程序時它會檢測到設備,但它在運行後不會檢測到新設備。Objective c/c:僅在Mac上通過IOKit檢測USB驅動器

//Just for testing 
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    [self detectUSB]; 
} 

void detectUSB() 
{ 
    //dictionary 
    CFMutableDictionaryRef matchingDict = matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 

    //create notification 
    IONotificationPortRef notificationObject; //notification object to listen 
    mach_port_t masterPort = 0; //received from IOMasterPort 
    notificationObject = IONotificationPortCreate(masterPort); 

    //create run loop 
    CFRunLoopSourceRef notificationRunLoopSource; 

    //use notification obejct received from notificationPortCreate 
    notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationObject); 

    CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode); 

    IOServiceAddMatchingNotification(notificationObject,kIOFirstMatchNotification, matchingDict,isAttached,(__bridge void*)self,&iter); 

    isAttached(NULL, iter); 
} 

void isAttached(void *refcon, io_iterator_t iterator) { 

    io_service_t usbDevice; 
    while((usbDevice = IOIteratorNext(iterator))) { 
     io_name_t name; 
     IORegistryEntryGetName(usbDevice, name); 
     printf("\tName:\t\t%s\n", (char *)name); 

     CFNumberRef idProduct = (CFNumberRef)IORegistryEntrySearchCFProperty(usbDevice, kIOServicePlane, CFSTR("idProduct"), kCFAllocatorDefault, 0); 
     uint16_t PID; 
     CFNumberGetValue(idProduct, kCFNumberSInt16Type, (void *)&PID); 
     printf("\tidProduct:\t0x%x\n", PID); 

     IOObjectRelease(usbDevice); 
     CFRelease(idProduct); 
     } 
    IOObjectRelease(iterator); 
} 

更何況,如果我拔掉USB驅動器之一,我應該如何檢測?我應該多加一個

​​

是isAttached函數之後嗎?其實我加了,但它給了我錯誤的訪問錯誤。你們能告訴我如何處理這些問題嗎?謝謝!!

回答

3

問題在於處理函數中的IOObjectRelease()調用。只要您想接收這些通知,您就需要堅持從IOServiceAddMatchingNotification獲得的迭代器。如果您刪除釋放呼叫,則代碼有效。

至於你的第二個問題:由於matchingDictIOServiceAddMatchingNotification發佈,該調用會導致訪問錯誤。如果您在調用之前執行CFRetain(matchingDict),則可以使用相同的匹配字典添加第二個通知。 (順便說一句:如果你對設備刪除通知感興趣,你應該通過kIOTerminatedNotification而不是kIOFirstMatchNotification

+0

順便說一句:你還需要添加兩個不同的源到runloop。 – valvoline

相關問題