Reputation: 403
I'm having trouble with some objective-c in Xcode. I'm trying to adapt an example from the DiskArbitration framework, and I'm getting stuck. This example sets a callback whenever the framework sees a disk. From the callback, I want to update a label.
@interface AVRecorderDocument ()
@property (assign) IBOutlet NSTextField *labelSpaceLeft;
@end
@implementation AVRecorderDocument
....
-id(init){
...
DASessionRef sessionDA = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(sessionDA, kDADiskDescriptionMatchVolumeMountable, diskAppearedCallback, 0);
DASessionScheduleWithRunLoop(sessionDA, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
...
}
static void diskAppearedCallback(DADiskRef disk, void* context)
{
CFDictionaryRef description = DADiskCopyDescription(disk);
NSLog(@"Disk appeared: %@", description);
NSLog(@"Disk Name: %@", CFDictionaryGetValue(description, CFSTR("DADeviceModel")));
// [_labelSpaceLeft setStringValue:[NSString CFDictionaryGetValue(description, CFSTR("DADeviceModel"))]];
CFRelease(description);
}
...
@end
The commented line inside the static function is what i've tried, but I get a "Use of undeclared identifier" error.
I've also tried converting the function to a method, which the compiler is ok with, but then I don't know how to properly call this from the DARegisterDiskAppearedCallback line at the top.
-(void)diskAppearedCallback:(DADiskRef *)disk context:(void *)context{
CFDictionaryRef description = DADiskCopyDescription(*disk);
NSLog(@"Disk appeared: %@", description);
NSString *spaceLeft = CFDictionaryGetValue(description, CFSTR("DADeviceModel"));
NSLog(@"Disk Name: %@", CFDictionaryGetValue(description, CFSTR("DADeviceModel")));
[labelSpaceLeft setStringValue:[NSString stringWithFormat: @"%@", spaceLeft]];
CFRelease(description);
}
**UPDATE: Here is a gist of the project: https://gist.github.com/anonymous/cb1c5795536ca15ef4e3
Upvotes: 0
Views: 254
Reputation: 9721
OK so the issue is that you are basically mixing C and Objective-C. The callback function diskAppearedCallback
is a C function and is not part of that class, even though it is defined between @implementation
and @end
. It therefore doesn't have access to _labelSpaceLeft
.
To fix the issue you need to get the callback function to call a method on that class instance, so when registering the callback, pass the instance in the last parameter. This is precisely what context pointers are for in callback functions.
DARegisterDiskAppearedCallback(sessionDA,
kDADiskDescriptionMatchVolumeMountable,
diskAppearedCallback,
self); // HERE
and then context
in the callback function will be a pointer to the class instance:
static void diskAppearedCallback(DADiskRef disk, void* context) {
CFDictionaryRef description = DADiskCopyDescription(*disk);
NSLog(@"Disk appeared: %@", description);
NSString *spaceLeft = CFDictionaryGetValue(description, CFSTR("DADeviceModel"));
NSLog(@"Disk Name: %@", CFDictionaryGetValue(description, CFSTR("DADeviceModel")));
// HERE
AVRecorderDocument *instance = (AVRecorderDocument *)context;
[instance.labelSpaceLeft setStringValue:spaceLeft];
CFRelease(description);
}
Upvotes: 2