objective-c – 如何为对象指针指针(id *)选择ARC桥接说明符?

我在NSArray上写了一个方便的方法,就像
PHP的list()函数一样,用于将数组“解包”到不同的对象中:

- (void)unpackInto:(__strong id *)obj1, ...
{
    __strong id *idPtr;
    va_list args;
    va_start(args, obj1);

    idPtr = obj1;
    NSUInteger idx = 0;
    NSUInteger count = [self count];
    while (idPtr != NULL && idx < count) {
        *idPtr = [self objectAtIndex:idx];

        // Increment the args and idx count
        idx++;
        idPtr = va_arg(args, __strong id *);
    }
}

我最初有__autoreleasing id *但在一个线程上调用此方法(实际上是两次,如果它很重要)时遇到了EXC_BAD_ACCESS问题,该线程有自己的自动释放池将内容解压缩到临时本地堆栈变量中.当主线程出现并尝试自动释放内容时(再次),抛出了EXC_BAD_ACCESS.

在这种情况下,任何人都可以帮助我遵循这些桥接参数的逻辑吗?我担心__strong会导致稍微不那么明显但同样邪恶的双胞胎表兄:内存泄漏……

最佳答案 我没有看到您的源代码,但如果您考虑所有权而不是保留/释放/自动释放池,则可以解决大多数ARC问题的答案.尝试回答,谁拥有数组谁拥有解压缩指针.如果我理解正确,你的调用方法看起来像这样

  NSArray *arr = [NSArray arrayWithObjects:@"a", @"b", @"c", @"d", nil];

  NSString *a, *b, *c, *d;
  [arr unpackInto:&a, &b, &c, &d, nil];

在访问解压缩的变量之前,您的数组是否已取消分配?请记住__autoreleasing不会将值“保留”到变量参数指针上.因此,如果您的数组被释放,您的指针就会变成垃圾.
我猜,你的EXC_BAD_ACCESS是因为你的主阵列被解除分配了.

通过引用返回时不应使用__strong.它不会增加保留计数.没有办法让ARC知道,这些变量将在调用方法中释放.因此ARC在其范围之后发布它们.将分配的对象传递给调用方法并让调用方法解除分配的唯一方法是从属于init-系列的方法返回它.当您跨方法边界返回值时,ARC使用方法系列(或宏NS_RETURNS_RETAINED / NS_RETURNS_NON-RETAINED)来确定谁“拥有”指针.

如果传递一个const指针(非写回指针),可以使用__strong按引用传递.事实上,对于没有所有权限定符的const指针,隐含__strong.

有关LLVM文档的更多信息,请参见此处
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.restrictions.pass_by_writeback

点赞