OSX上的Delphi:如何将CFDictionaryRef转换为NSDictionary?

时间:2017-05-29 09:55:43

标签: macos delphi firemonkey

根据Apple documentation CFDictionaryRefNSDictionary Toll-Free Bridged Types。 但是,我在下面的代码中得到了一个AV,这可能是因为该桥不适用于Delphi。

DADiskCopyDescription返回CFDictionaryRef,我将其换行到NSDictionary。指针不是NIL,但当我访问对象中的一个函数时,我得到一个AV:

function osxGetRootVolumeUUID: string;
var lNSDictionary: NSDictionary;
    lDisk: DADiskRef;
    lCFUrl: CFURLRef;
    lSession: DASessionRef;
    lUUID: CFUUIDRef;
begin
  result := '';
  lSession := DASessionCreate(nil);
  lCFUrl := TNSURL.OCClass.fileURLWithPath(StrToNSStr('/'));
  lDisk := DADiskCreateFromVolumePath(nil,lSession,lCFUrl);
  lNSDictionary := TNSDictionary.Wrap(DADiskCopyDescription(lDisk));

  lUUID := lNSDictionary.objectForKey(kDADiskDescriptionVolumeUUIDKey); //<- AV here

  if lUUID<>nil then
    result := CFStringRefToStr( CFUUIDCreateString(nil, lUUID));
  lNSDictionary.release;
  CFRelease(lCFurl);
end;

我还尝试按this SO question中的建议使用CFBridgingRelease,但错误SIGABRT (6)

lNSDictionary := TNSDictionary.Wrap(CFBridgingRelease(DADiskCopyDescription(lDisk))); //gives error: SIGABRT (6)

如何让它发挥作用?

PS。基本上我只想获得OSX上的根卷UUID。上面的函数从我们目前使用的Objective-C函数转换为Delphi。

修改

我尝试过的另一件事是避免使用NSDictionary,但这也会产生错误,这可能表明问题是其他问题:

lCFDictionaryRef := DADiskCopyDescription(lDisk);
lUUID := CFDictionaryGetValue(lCFDictionaryRef, kDADiskDescriptionVolumeUUIDKey); //<- AV here

1 个答案:

答案 0 :(得分:1)

要将CFDictionaryRef转换为TNSDictionary,您必须这样做:

(xxx as ILocalObject).GetObjectID

所以这里的一切都很好,不过我想也许你的av就是你访问对象的方式。不要忘记在IOS中总是使用getObjectID而不是指向对象的指针

例如:传递给ios api xxx并且永远不会直接传递给IOS api (kDADiskDescriptionVolumeUUIDKey as ILocalObject).GetObjectID

所以也许它必须是Animation Type或类似的东西