3

这是我的代码,它会在我第一次运行应用程序时检测到设备,但在运行后它不会检测到新设备。

//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 驱动器,我应该如何检测?我应该再添加一个

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

在 isAttached 函数之后?实际上我添加了但它给了我糟糕的访问错误。你们能告诉我如何处理这些问题吗?谢谢!!

4

1 回答 1

4

问题在于IOObjectRelease()您的处理程序函数中的调用。IOServiceAddMatchingNotification只要您想接收这些通知,您就需要保留从 获得的迭代器。如果您删除发布调用,代码将起作用。

至于你的第二个问题:调用给出了错误的访问错误,因为matchingDictIOServiceAddMatchingNotification. 如果您CFRetain(matchingDict)在该调用之前进行了一次,则可以使用相同的匹配字典添加第二个通知。(顺便说一句:如果您对设备移除通知感兴趣,您应该通过kIOTerminatedNotification而不是。kIOFirstMatchNotification

于 2013-12-13T15:04:12.507 回答