在回调方法中枚举磁盘时 DiskRef 消失

DiskRef disappears while enumerating disks in callback method

我在我正在处理的项目 GitHub 上使用了项目 Disk-Arbitrator 中的 DiskArbitration 类。

我是 mounting/unmounting OS X Installer Disk Images via hdiutil 有时为 DARegisterDiskDescriptionChangedCallback 定义的回调方法会崩溃,因为磁盘列表在枚举时发生了变化,并且然后 get 传递的 diskref 变为 NULL.

这是为回调调用的 get 函数:

DARegisterDiskDescriptionChangedCallback(session, matching, NULL, DiskDescriptionChangedCallback, (__bridge void *)([NBCDisk class]));

...

void DiskDescriptionChangedCallback(DADiskRef diskRef, CFArrayRef keys, void *context) {
#pragma unused(keys)
    if (context != (__bridge void *)([NBCDisk class])) return;

    NSSet *uniqueDisksCopy = [uniqueDisks copy];
    for ( NBCDisk *disk in uniqueDisksCopy ) {
        if ( CFHash(diskRef) == [disk hash] ) {
            CFDictionaryRef desc = DADiskCopyDescription(diskRef);
            disk.diskDescription = desc;
            CFRelease(desc);

            [[NSNotificationCenter defaultCenter] postNotificationName:DADiskDidChangeNotification object:disk];
        }
    }
}

我通过复制并枚举解决了枚举时发生变异的问题。

但是,此代码有时会崩溃:"*** CFHash() called with NULL ***"

那是因为磁盘已经消失并且 diskRef 可能已经被释放。

所以,我需要一些提示。我想尝试复制 diskRef,并尝试这样做:

DADiskRef diskRefCopy = diskRef;

但这也没有用。还有其他方法可以复制吗?或者我应该用另一种方法来解决这个问题。

So, I need some tips here. I wanted to try and make a copy of the diskRef, and tried that by doing this:

DADiskRef diskRefCopy = diskRef;

由于您正在与 Core Foundation 互动;使用 -

CFRetain(diskRef);

此外,请查看 Disk-Arbitrator project, File is Disk.m at line #80 中的以下参考资料:

disk = CFRetain(diskRef);

#75行:

return [uniqueDisk retain];

希望对您有所帮助!顺便说一句,不需要复制 NSSet *uniqueDisksCopy = [uniqueDisks copy];.