gpt4 book ai didi

objective-c - 如何在 ARC 中从 id __autoreleasing * 转换为 void **?

转载 作者:搜寻专家 更新时间:2023-10-30 19:44:24 25 4
gpt4 key购买 nike

我正在尝试从 id __autoreleasing * 转换为 CFTypeRef * (void **)。

我试过:

id __autoreleasing *arg = [OCMArg setTo:mockData];

CFTypeRef expectedResult = (__bridge CFTypeRef) *arg;

[[[self.mockSecItemService expect] andReturnValue:OCMOCK_VALUE(mockCopyStatus)] copyItemMatching:queryCheck
result:&expectedResult];

但是当自动释放池被耗尽时代码崩溃。

如何在 ARC 环境中转换为 void**?

最佳答案

我不知道您使用的 API,所以我不能 100% 确定发生了什么。我用谷歌搜索,它们似乎是 OCMock 的一部分。我下载了它(因为我不感兴趣,所以没有安装)我快速浏览了源代码。

我在该代码中看到了一些可疑的东西。以下是他们如何实现您调用的第一个方法:

@implementation OCMArg

....

+ (id *)setTo:(id)value
{
return (id *)[[[OCMPassByRefSetter alloc] initWithValue:value] autorelease];
}

所以他们返回一个 id*,它实际上只是一个 id

对我来说,这要么是胡说八道/错误,要么是试图操纵 ObjC 内部结构(即使没有记录,ObjC 对象存储的第一件事实际上是指向对象类的指针,因此类型为 Classid 兼容,因此以某种方式将指向对象的指针或引用对象的 id 转换为 Class*< 是有效的id*)。我没有时间也没有兴趣去研究整个 API 来弄清楚他们为什么这样做。他们实际上可能有充分的理由(例如,如果您只将该结果传递给另一个知道它应该是什么的 API,但您在这里做的不止于此)。我不会研究 OCMock,而是会尽量向您解释正在发生的事情(ObjC 和 ARC)。

id __autoreleasing *arg = [OCMArg setTo:mockData];

ARC 在这行代码中绝对不会做任何事情。

上面那个方法是干什么的。 OCMPassByRefSetter 类是一个简单的类,它只是在保留参数后存储参数,因此保留了 mockDataOCMPassByRefSetter 是自动释放的,将在下一次耗尽时消失(释放 mockData 使 *arg 引用已释放内存)。

注意arg实际上指向OCMPassByRefSetterisa(isa是“第一个"任何对象的 ivar,它是 Class 类型并指向对象的类。但这没有记录并且可能随时更改)。

CFTypeRef expectedResult = (__bridge CFTypeRef) *arg;

*arg 是与 CFTypeRef 兼容的 id 类型,因此转换有效。你使用 __bridge 所以 ARC 什么都不做。

如果 arg 指向“免费桥接”CF/Cocoa 类,这将是完全有效的代码,但您必须小心 expectedResult 会变得无效在下一个 drain 中(它不是 retained,而是作为一个自动释放的实例存在)。

[[[self.mockSecItemService expect] andReturnValue:OCMOCK_VALUE(mockCopyStatus)] copyItemMatching:queryCheck
result:&expectedResult];

不知道这一行是做什么的。鉴于您在上面的评论中发布的原型(prototype),ARC 对 result:&expectedResult 部分不执行任何操作。

你说它是 SecItemCopyMatching 的包装器,但据我了解,它不止于此。如果它只是立即调用 SecItemCopyMatching 并将 result: 参数传递给它,您可能会把事情搞砸。但是名称 expectedResult 以及这是 OCMock 这一事实让我觉得这比那更复杂一些。

您必须自己调查一下。但请记住:

  • 一旦当前函数退出,您传递的参数 (&expectedResult) 将失效,因为它是局部变量。
  • 一旦出现耗尽,expectedResult将变为无效,因为该地址指向将被耗尽释放的内存。
  • expectedResult 的值做任何事情 很可能会出错,因为我不认为 Class 有资格作为“收费”免费桥接”。

我怀疑,但我可能错了,您没有按照预期的方式使用 OCMock api。但在这方面我帮不了你,也许你真的做对了。

关于objective-c - 如何在 ARC 中从 id __autoreleasing * 转换为 void **?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11939665/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com