[英]Disk Arbitration and OK button issue
The code below is used to get the list of disks 下面的代码用于获取磁盘列表
(void)da_tools
{
DASessionRef session;
session = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(session, NULL, disk_appeared_callback, (void *)NULL);
DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRunLoopRun();
CFRelease(session);
}
The IBAction for the OK button is: [self da_tools]
; OK按钮的IBAction是: [self da_tools]
;
The callback function disk_appeared_callback works perfectly and give the right information. 回调函数disk_appeared_callback可以完美工作并提供正确的信息。
The problem happens at CFRunLoopRun() when the OK button is hit: 单击确定按钮时, CFRunLoopRun()会发生问题:
However any key press to the keyboard (or a mouse click everywhere (and sometime just a mouse move)) force CFRunLoopRun() to exit and the callback function disk_appeared_callback is promptly executed. 但是,任何对键盘的按键操作(或在任何地方单击鼠标(有时只是鼠标移动))都将强制CFRunLoopRun()退出,并立即执行回调函数disk_appeared_callback 。
When CFRunLoopRun() is removed da_tools
does not return any disk information at the first OK button hit but subsequent OK button hit returns the correct disk information. 当删除CFRunLoopRun()时 , da_tools
在第一次单击OK按钮时不返回任何磁盘信息,但随后单击OK按钮则返回正确的磁盘信息。
I have tried to include da_tools
in an another thread: 我试图在另一个线程中包含da_tools
:
[NSThread detachNewThreadSelector:@selector(da_tools) toTarget:self withObject:nil]
but this doesn't help. 但这无济于事。
I also tried to post a keydown event but this fails too. 我也尝试发布一个keydown事件,但这也失败了。
How to use CFRunLoopRun correctly? 如何正确使用CFRunLoopRun ?
Please do not to use call CFRunLoopRun();
请不要使用调用CFRunLoopRun();
method separately and please not release session CFRelease(session);
方法,请不要释放会话CFRelease(session);
because you will not received any callback later on. 因为您以后将不会收到任何回调。
How to established session with DiskArbitration and listen via callbacks? 如何与DiskArbitration建立会话并通过回调进行监听?
Creating DA session and schedule session run loop: 创建DA会话并安排会话运行循环:
// Disk Arbitration Session
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
if (!session) {
[NSException raise:NSGenericException format:@"Unable to create Disk Arbitration session."];
return;
}
NSLog(@"Disk Arbitration Session created");
// schedule DA session run loop
DASessionScheduleWithRunLoop(session, CFRunLoopGetMain(), kCFRunLoopCommonModes);
If you like to listen for all disk events including internal one. 如果您想监听所有磁盘事件,包括内部事件。 Then Pass NULL
while registering callbacks. 然后在注册回调时传递NULL
。
Else create a matching condition
for your callbacks. 否则为您的回调创建一个matching condition
。 For example: following condition for external hard disk, memory disk connects via USB. 例如:对于外部硬盘,在满足以下条件时,存储磁盘通过USB连接。
// Matching Conditions
CFMutableDictionaryRef match = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Device matching criteria
// 1. Of-course it shouldn't be internal device since
CFDictionaryAddValue(match, kDADiskDescriptionDeviceInternalKey, kCFBooleanFalse);
// Volume matching criteria
// It should statisfy following
CFDictionaryAddValue(match, kDADiskDescriptionVolumeMountableKey, kCFBooleanTrue);
CFDictionaryAddValue(match, kDADiskDescriptionVolumeNetworkKey, kCFBooleanFalse);
Look at DADisk.h
, we add more conditions for your need. 查看DADisk.h
,我们将为您添加更多条件。
Registering Callbacks with DiskArbitration, more info on callbacks here - 使用DiskArbitration注册回调,有关回调的更多信息,在这里 -
NSString * const AppName = @"DAApp";
// Registring callbacks
DARegisterDiskAppearedCallback(session, match, DiskAppearedCallback, (__bridge void *)AppName);
DARegisterDiskDisappearedCallback(session, match, DiskDisappearedCallback, (__bridge void *)AppName);
DARegisterDiskDescriptionChangedCallback(session, match, NULL, DiskDescriptionChangedCallback, (__bridge void *)AppName);
// And now release match
CFRelease(match);
... Application things goes around...** ...应用程序随处可见... **
Finally Unregister and release everything. 最后,取消注册并释放所有内容。 Typical place is application terminate or dealloc. 典型的地方是应用程序终止或释放。
// DA Session
if (session) {
DAUnregisterCallback(session, DiskAppearedCallback, (__bridge void *)AppName);
DAUnregisterCallback(session, DiskDisappearedCallback, (__bridge void *)AppName);
DASessionUnscheduleFromRunLoop(session, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(session);
NSLog(@"Disk Arbitration Session destoryed");
}
I hope it helps! 希望对您有所帮助!
BTW, for DA Approval Session like this BTW,用于像这样的DA批准会议
// Disk Arbitration Approval Session
DASessionRef approvalSession = DAApprovalSessionCreate(kCFAllocatorDefault);
if (!approvalSession) {
NSLog(@"Unable to create Disk Arbitration approval session.");
return;
}
NSLog(@"Disk Arbitration Approval Session created");
DAApprovalSessionScheduleWithRunLoop(approvalSession, CFRunLoopGetMain(), kCFRunLoopCommonModes);
// Same match condition for Approval session too
DARegisterDiskMountApprovalCallback(approvalSession, match, DiskMountApprovalCallback, (__bridge void *)AppName);
// may need CFRelease(match); based code sequence!
Finally unregister and release. 最后注销并释放。
// DA Approval Session
if (approvalSession) {
DAUnregisterApprovalCallback(approvalSession, DiskMountApprovalCallback, (__bridge void *)AppName);
DAApprovalSessionUnscheduleFromRunLoop(approvalSession, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(approvalSession);
NSLog(@"Disk Arbitration Approval Session destoryed");
}
For more info on above code snippets here . 有关以上代码的详细信息网页摘要这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.