3

I am just starting out in this wacky world of programming and I have come across a very frustrating problem:

I am trying to use Disk Arbitration Framework to put all Disks in a array.

#import "DiskDetector.h"
#import "Disk.h"
@implementation DiskDetector

-(id)init {
    self.arrayOfDisks = [[NSMutableArray alloc]init];
    DASessionRef session;

    session = DASessionCreate(kCFAllocatorDefault);

    DARegisterDiskAppearedCallback(session, kDADiskDescriptionMatchVolumeMountable,diskAppearedCallback,NULL);
    DARegisterDiskDisappearedCallback(session,kDADiskDescriptionMatchVolumeMountable, diskDisappearedCallback, NULL);
    DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);


    return self;
}
-(void)addToArrayOfDisks:(Disk*)disk {

}

void diskAppearedCallback(DADiskRef disk, void* context)
{
    Disk *theDisk = [[Disk alloc]initWithNewDisk:disk];
    NSLog(@"Disk Name: %@",theDisk.diskName);
    NSLog(@"Disk Number: %@",theDisk.diskBSDName);
    NSLog(@"Disk Connection Type: %@",theDisk.diskConnection);
    NSLog(@"Disk Capacity in Bytes: %@",theDisk.diskTotalCapacityInBytes);
    NSLog(@"Volume Name: %@",theDisk.partitionScheme);

    //How Do I return "theDisk" from this function?
    //[self.arrayOfDisks addObject:theDisk] does not work...complier has problem with    use of "self"
}

void diskDisappearedCallback(DADiskRef disk, void* context)
{
    NSLog(@"%s was ejected", DADiskGetBSDName(disk));
}


@end

As you can see, everything logs okay. The issue is that I want to return "theDisk" object in some way So I can work with it.

Since the callback function is void, I cannot do a return statement. If I attempt to modify the function's return type the DARegisterDiskAppearedCallback Function will not work entirely.

Again, my only goal here is to get information about all disks and partitions on computer and put them in an array so I can get info about them and manipulate them.

Also, can anyone explain when one would put something in "(void*)context" in the callback function? Apple Documentation is very vague on this...or maybe I am missing something entirely

1 Answers1

1

The context parameter is for your use. You can set whatever you want as the context, and DiskArbitration will pass it to you when it calls the callback. You can use this to solve your first problem by passing your DiskDetector object as the context:

-(id)init {
    // ...
    DARegisterDiskAppearedCallback(session, kDADiskDescriptionMatchVolumeMountable, diskAppearedCallback, self);
    // ...
}
void diskAppearedCallback(DADiskRef disk, void* context) {
    DiskDetector *detector = (DiskDetector *)context;
    // ...
    [detector.arrayOfDisks addObject:theDisk];
}
Greg Parker
  • 7,972
  • 2
  • 24
  • 21
  • This was very helpful. However, When I added your code I am now getting two errors DARegisterDiskAppearedCallback(session, kDADiskDescriptionMatchVolumeMountable, diskAppearedCallback, self); reports a "Implicit conversion of Objective-C pointer type 'disk detector *' to C point type 'void *' requires a bridge cast and the other line gives a similar message also requiring a bridge cast. problem is when I add the __bridge cast between Core Foundation and Foundation I then get a runtime error on the callback function. What is going on? – user3689657 May 30 '14 at 04:11
  • You're using ARC. ARC requires extra annotations when storing Objective-C object pointers in variables of type void*. The correct fix depends on what memory management behavior you want. One fix is to use `CFBridgingRetain()` when you install the callback and `(__bridge DiskDetector *)` inside the callback. That will make your DiskDetector object live forever; that could be OK or a leak, depending on what your program does. – Greg Parker May 30 '14 at 18:17
  • This makes sense...however this doesn't fix my second issue...which is how am I going to put the "Disk Objects" generated inside the callback into an NSMutableArray (That is outside the scope of the callback)? The idea behind the program is to make a tableview kind of like DiskUtility...where when you plug a drive in the callback makes an object out of that disk (containing all the stuff I logged about it) and puts that object into a NSMutableArray which will be the DataSource for my tableview. Am I just going about this the wrong way? I hope this helps...cuz I am in a serious jam here – user3689657 May 31 '14 at 06:00