使用 DiskArbitration 卸载 OSX 中的磁盘
Unmount disk in OSX with DiskArbitration
我正在尝试卸载 OSX 中的磁盘。代码工作正常,但只有在出现错误时才成功卸载磁盘时不会调用回调。我阅读了 DiskArbitrationProgGuide 并按照步骤操作,但还没有任何进展。有人可以帮我吗?
@interface DriverUtilitiesController()
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context);
@end
+ (void)umnountDrivePath:(NSString *)voulumePath
{
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
CFURLRef path = CFURLCreateWithString(NULL, (__bridge CFStringRef)voulumePath, NULL);
DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path);
DADiskUnmount(disk, kDADiskUnmountOptionDefault, unmount_done, NULL);
CFRelease(disk);
}
#pragma mark - Unmount Callback
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context)
{
NSLog(@"Inside unmount_done");
if (dissenter)
{
// Unmount failed. //
NSLog(@"Unmount failed.");
} else {
NSLog(@"Unmounted Volume");
}
}
正在更新。 感谢 Ken Thomases 代码现在可以工作了
- (id)init
{
self = [super init];
self.session = DASessionCreate(kCFAllocatorDefault);
DASessionScheduleWithRunLoop(_session, [[NSRunLoop mainRunLoop] getCFRunLoop], kCFRunLoopDefaultMode);
return self;
}
- (void)umnountDrivePath:(NSString *)voulumePath
{
CFURLRef path = CFURLCreateWithString(NULL, (__bridge CFStringRef)voulumePath, NULL);
DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, self.session, path);
DADiskUnmount(disk, kDADiskUnmountOptionDefault, unmount_done, (__bridge void *)(self));
CFRelease(disk);
}
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context)
{
if (dissenter)
{
// Unmount failed. //
NSLog(@"Unmount failed.");
} else {
NSLog(@"Unmounted Volume");
}
DriverUtilitiesController *driverUtilitiesController = (__bridge DriverUtilitiesController *)context;
[driverUtilitiesController clearUnmountCallback];
}
- (void)clearUnmountCallback
{
DASessionUnscheduleFromRunLoop(_session, [[NSRunLoop mainRunLoop] getCFRunLoop], kCFRunLoopDefaultMode);
CFRelease(self.session);
}
DADiskUnmount()
异步操作。在函数 returns 到您的代码时,磁盘不一定已卸载。如果成功,它可能会在稍后发生。届时将回拨您的电话。
程序等待该事件并调用您的回调作为响应的机制是 运行 循环或调度队列。会话对象负责管理这个等待和调用。您需要在 运行 循环或调度队列上安排会话对象。您可以使用 DASessionScheduleWithRunLoop()
或 DASessionSetDispatchQueue()
,如 Disk Arbitration Programming Guide: Using Disk Arbitration Notification and Approval Callbacks – Scheduling the Session with the Run Loop or Dispatch Queue.
中所述
这意味着您不想为每次尝试卸载磁盘都创建一个新的会话对象。此外,您希望保留对会话对象的引用,以便您可以在不再需要它时取消计划并释放它(这将是在您不再需要从它获取回调之后的某个时间)。
我正在尝试卸载 OSX 中的磁盘。代码工作正常,但只有在出现错误时才成功卸载磁盘时不会调用回调。我阅读了 DiskArbitrationProgGuide 并按照步骤操作,但还没有任何进展。有人可以帮我吗?
@interface DriverUtilitiesController()
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context);
@end
+ (void)umnountDrivePath:(NSString *)voulumePath
{
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
CFURLRef path = CFURLCreateWithString(NULL, (__bridge CFStringRef)voulumePath, NULL);
DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path);
DADiskUnmount(disk, kDADiskUnmountOptionDefault, unmount_done, NULL);
CFRelease(disk);
}
#pragma mark - Unmount Callback
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context)
{
NSLog(@"Inside unmount_done");
if (dissenter)
{
// Unmount failed. //
NSLog(@"Unmount failed.");
} else {
NSLog(@"Unmounted Volume");
}
}
正在更新。 感谢 Ken Thomases 代码现在可以工作了
- (id)init
{
self = [super init];
self.session = DASessionCreate(kCFAllocatorDefault);
DASessionScheduleWithRunLoop(_session, [[NSRunLoop mainRunLoop] getCFRunLoop], kCFRunLoopDefaultMode);
return self;
}
- (void)umnountDrivePath:(NSString *)voulumePath
{
CFURLRef path = CFURLCreateWithString(NULL, (__bridge CFStringRef)voulumePath, NULL);
DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, self.session, path);
DADiskUnmount(disk, kDADiskUnmountOptionDefault, unmount_done, (__bridge void *)(self));
CFRelease(disk);
}
void unmount_done(DADiskRef disk,
DADissenterRef dissenter,
void *context)
{
if (dissenter)
{
// Unmount failed. //
NSLog(@"Unmount failed.");
} else {
NSLog(@"Unmounted Volume");
}
DriverUtilitiesController *driverUtilitiesController = (__bridge DriverUtilitiesController *)context;
[driverUtilitiesController clearUnmountCallback];
}
- (void)clearUnmountCallback
{
DASessionUnscheduleFromRunLoop(_session, [[NSRunLoop mainRunLoop] getCFRunLoop], kCFRunLoopDefaultMode);
CFRelease(self.session);
}
DADiskUnmount()
异步操作。在函数 returns 到您的代码时,磁盘不一定已卸载。如果成功,它可能会在稍后发生。届时将回拨您的电话。
程序等待该事件并调用您的回调作为响应的机制是 运行 循环或调度队列。会话对象负责管理这个等待和调用。您需要在 运行 循环或调度队列上安排会话对象。您可以使用 DASessionScheduleWithRunLoop()
或 DASessionSetDispatchQueue()
,如 Disk Arbitration Programming Guide: Using Disk Arbitration Notification and Approval Callbacks – Scheduling the Session with the Run Loop or Dispatch Queue.
这意味着您不想为每次尝试卸载磁盘都创建一个新的会话对象。此外,您希望保留对会话对象的引用,以便您可以在不再需要它时取消计划并释放它(这将是在您不再需要从它获取回调之后的某个时间)。