这是我的代码,它会在我首先运行应用程序时检测设备,但在运行后它不会检测到新设备。
//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函数之后?实际上我添加但它给了我错误的访问错误。你能告诉我如何处理这些问题吗?谢谢!
答案 0 :(得分:3)
问题在于处理程序函数中的IOObjectRelease()
调用。只要您想接收这些通知,就需要保留从IOServiceAddMatchingNotification
获得的迭代器。如果您删除了发布调用,则代码可以正常运行。
关于你的第二个问题:调用会产生错误的访问错误,因为matchingDict
会释放IOServiceAddMatchingNotification
。如果您在该呼叫之前执行CFRetain(matchingDict)
,则可以使用相同的匹配字典添加第二个通知。 (顺便说一句:如果您对设备删除通知感兴趣,则应该通过kIOTerminatedNotification
而不是kIOFirstMatchNotification
。