Я снова борюсь с утечкой памяти, и мне нужна помощь, чтобы разобраться с этим. Я знаю (или почти уверен), что проблема в CFSet.
Я предполагаю, что мне нужно использовать CFRelease (), но я не уверен, как это сделать, поскольку мне также нужно вернуть CFSet в USBDeviceCount (). Любая помощь будет оценена! Спасибо!
Вот код (который, похоже, прекрасно работает! За исключением утечек):
// New USB device has been added (callback function)
static void Handle_DeviceMatchingCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
// Log the device ID & device count
NSLog(@"\nNew USB device: %p\nDevice count: %ld",
(void *)inIOHIDDeviceRef,
USBDeviceCount(inSender));
}
// USB device has been removed (callback function)
static void Handle_DeviceRemovalCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
// Log the device ID & device count
NSLog(@"\nUSB device removed: %p\nDevice count: %ld",
(void *)inIOHIDDeviceRef,
USBDeviceCount(inSender));
}
// Counts the number of devices in the device set (includes all USB devices that match dictionary)
static long USBDeviceCount(IOHIDManagerRef HIDManager)
{
// The device set includes all USB devices that match our matching dictionary. Fetch it.
CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager);
// The devSet will be NULL if there are 0 devices, so only try to count the devices if devSet exists
if(devSet) return CFSetGetCount(devSet);
// There were no matching devices (devSet was NULL), so return a count of 0
return 0;
}
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
// Create an HID Manager
IOHIDManagerRef HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
// Create a Matching Dictionary
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(
kCFAllocatorDefault,
2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Specify a device manufacturer in the Matching Dictionary
CFDictionarySetValue(matchDict,
CFSTR(kIOHIDTransportKey),
CFSTR("USB"));
// Register the Matching Dictionary to the HID Manager
IOHIDManagerSetDeviceMatching(HIDManager, matchDict);
// Register a callback for USB device detection with the HID Manager
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &Handle_DeviceMatchingCallback, NULL);
// Register a callback fro USB device removal with the HID Manager
IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, &Handle_DeviceRemovalCallback, NULL);
// Register the HID Manager on our app’s run loop
IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
// Open the HID Manager
IOReturn IOReturn = IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone);
if(IOReturn) NSLog(@"IOHIDManagerOpen failed."); // Couldn't open the HID manager!
CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager);
CFRelease(devSet);
CFRelease(matchDict);
}
Для полноты, вот решение, которое я смог реализовать с помощью Карла (спасибо, Карл !!):
AppDelegate.h:
- (void) updateConnectedUSBs;
@property(retain) __attribute__((NSObject)) IOHIDManagerRef hidManager;
@property (strong) NSSet *usbDeviceSet;
AppDelegate.m:
// New USB device has been added (callback function)
static void Handle_DeviceMatchingCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
[appDelegate updateConnectedUSBs];
}
// USB device has been removed (callback function)
static void Handle_DeviceRemovalCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef){
AppDelegate *appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
[appDelegate updateConnectedUSBs];
}
- (void) updateConnectedUSBs {
CFSetRef devSet = IOHIDManagerCopyDevices(_hidManager);
self.usbDeviceSet = CFBridgingRelease(devSet);
NSLog(@"%@",self.usbDeviceSet);
}
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification
{
_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
// Create a Matching Dictionary
CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(
kCFAllocatorDefault,
2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Specify a device manufacturer in the Matching Dictionary
CFDictionarySetValue(matchDict,
CFSTR(kIOHIDTransportKey),
CFSTR("USB"));
// Register the Matching Dictionary to the HID Manager
IOHIDManagerSetDeviceMatching(_hidManager, matchDict);
// Register a callback for USB device detection with the HID Manager
IOHIDManagerRegisterDeviceMatchingCallback(_hidManager, &Handle_DeviceMatchingCallback, NULL);
// Register a callback fro USB device removal with the HID Manager
IOHIDManagerRegisterDeviceRemovalCallback(_hidManager, &Handle_DeviceRemovalCallback, NULL);
// Register the HID Manager on our app’s run loop
IOHIDManagerScheduleWithRunLoop(_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
// Open the HID Manager
IOReturn IOReturn = IOHIDManagerOpen(_hidManager, kIOHIDOptionsTypeNone);
if(IOReturn) NSLog(@"IOHIDManagerOpen failed."); // Couldn't open the HID manager!
CFRelease(matchDict);
}