首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AXUIElementRef和ARC -已分配实例和__bridge与__bridge_transfer

AXUIElementRef和ARC -已分配实例和__bridge与__bridge_transfer
EN

Stack Overflow用户
提问于 2013-03-13 10:24:41
回答 1查看 610关注 0票数 1

我在NSMutableArray上得到了这个错误:

代码语言:javascript
运行
复制
  -[Not A Type release]: message sent to deallocated instance 0x1006e29c0

这种情况发生在这条线上:

代码语言:javascript
运行
复制
     [_array removeAllObjects];

现在,我理解错误的含义,但不理解为什么会在这种情况下发生。

我在上面的行前面添加了一个NSLog,如下所示:

代码语言:javascript
运行
复制
      NSLog(@"%@", [_array class]);

这将正常执行,并具有正确的行为,这是日志:

代码语言:javascript
运行
复制
 2013-03-13 11:19:27.366 App[66921:303] __NSArrayM
 2013-03-13 11:19:27.367 App[66921:303] *** -[Not A Type release]: message sent to deallocated instance 0x1006e29c0

所以在移除它之前,它似乎并没有被释放。

即使我删除了removeAllObjects调用并用下面的行替换它,我仍然会得到相同的错误。

代码语言:javascript
运行
复制
     _array = [[NSMutableArray alloc] init];

在代码的其他部分,我所做的就是调用_array addObject:.

_array是一个强大的属性:

代码语言:javascript
运行
复制
@property (strong) NSMutableArray *array;

数组首先在init方法中初始化。

编辑:我将AXUIElementRefs添加到这个数组中,如下所示:

代码语言:javascript
运行
复制
 [_array addObject:(__bridge_transfer id)elementRef];

我以为__bridge_transfer会把它交给ARC,我就不需要管理这些了?

有什么问题吗?

更新:下面是一个示例项目: http://users.telenet.be/prullen/AXMemory.zip

这是一个工作项目,因为我使用的是__bridge而不是__bridge_transfer。

这个项目包含一个简单的循环,它一遍又一遍地做同样的事情。这是为了证明仅仅使用__bridge,AXUIElementRefs永远不会发布。他们会留在记忆里。这也是我在仪器分析器上看到的。您还可以通过活动监视器看到内存使用量每隔几秒增加一次。

AXUIElementRefs是通过AXUIElementCopyMultipleAttributeValues获得的,所以我会假设我拥有它们的所有权?然而,更改为__bridge_transfer会导致上述错误。

如果有人能看看这个,让我知道我做错了什么,那将是非常感谢的。

我通过以下语句获得一个属性数组:(第60行)。

代码语言:javascript
运行
复制
         AXUIElementCopyMultipleAttributeValues(frontWindowRef, attributes,0,&attributeValues);

第110行我分配AXUIElement (在子数组上循环):

代码语言:javascript
运行
复制
             element = CFArrayGetValueAtIndex(childrenArrayRef, i);

第112行是我将AXUIElementRef添加到数组的位置:

代码语言:javascript
运行
复制
             [_array addObject:(__bridge id)(element)];

如果超过500个元素,那么第36行就是我清空它的地方:

代码语言:javascript
运行
复制
if ([_array count] > 500) {
    [_array removeAllObjects];
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-13 13:02:40

你不能仅仅假设__bridge_transfer“把它带到了ARC,你就不需要管理这些了”。您必须了解当时您对elementRef有哪些权利和责任(我们无法从您所写的内容中看出这一点)。

如果使用相应的CFBridgingRetain()CFBridgingRelease()函数,我发现理解桥接转换要容易得多。__bridge_transferCFBridgingRelease()是一样的。所以,问题是:你当时拥有elementRef吗?你放了它合适吗?

考虑一下,以下内容是否是正确的?

代码语言:javascript
运行
复制
[_array addObject:(__bridge id)elementRef];
CFRelease(elementRef);

如果不是,那么__bridge_transfer也不是。

从您所得到的错误的本质来看,我强烈怀疑您无权发布elementRef,因此您无权告诉ARC它拥有它,并且必须释放它。你已经导致了AXUIElementRef的过度发布.您应该使用__bridge强制转换-不使用“传输”和不使用CF…Release()

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15382609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档