0

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

我正在通过hdiutil有时为DARegisterDiskDescriptionChangedCallback崩溃定义的回调方法安装/卸载 OS X 安装程序磁盘映像,因为磁盘列表在枚举时发生了变化,然后 get 传递的 diskref 变为NULL.

这是回调调用的函数:

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;

但这也不起作用。有没有其他方法可以复制?还是有另一种方法我应该解决这个问题。

4

1 回答 1

0

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

DADiskRef diskRefCopy = diskRef;

由于您正在与 Core Foundation 进行交互;利用 -

CFRetain(diskRef);

另外,请查看Disk-Arbitrator项目中的以下参考,文件是 Disk.m 在第#80行:

disk = CFRetain(diskRef);

第 75行:

return [uniqueDisk retain];

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

于 2015-06-19T19:40:55.100 回答