使用ARC将指针传递给NSArray内的对象

时间:2013-02-12 20:45:33

标签: objective-c pointers reference automatic-ref-counting bridge

我正在转换为ARC,并且在没有破坏代码的情况下找不到任何方法来摆脱这个编译错误。

我需要将2个对象传递给选择器,所以我将它们都添加到数组中,如下所示,并将该数组发送到选择器:

LWPagerContent* content = nil;
NSArray* args = [NSArray arrayWithObjects:article, [NSValue valueWithPointer:&content], nil];

[self performSelectorOnMainThread:@selector(initArticlePagerContent:) withObject:args waitUntilDone:YES];

此方法访问数组,但需要在数组中引用的地址处修改对象。它应该如图所示初始化LWPagerContent对象,然后该对象将被调用performSelector的原始方法使用。

- (void)initArticlePagerContent:(NSArray*)args {
Article* article = [args objectAtIndex:0];

LWPagerContent** contentPtr = [[args objectAtIndex:1] pointerValue];
*contentPtr = [[NSClassFromString([StyleSheet articleContentClass]) alloc] initWithArticle:article];

}

这很好用,但当我尝试转换为ARC时,我立即告诉"Implicit conversion of a non-Objective-C type 'void *' to 'LWPagerContent *__strong *' is disallowed with ARC"。在以"LWPagerContent **..."开头的行上发生此错误(上面显示的是第二个到最后一个)。我尝试过使用其他帖子中推荐的__bridge__autoreleasing,但似乎没有任何效果。任何建议都非常感谢。

3 个答案:

答案 0 :(得分:7)

使用块转到主线程,消除-performSelector:call暗示的元编程。

然后使用回调来设置生成的内容。

dispatch_sync(dispatch_get_main_queue(), ^{
    LWPagerContent *newContent = ... do something ...
    [self setPagerContent:newContent];
});

一些注意事项:

    不应将
  • 方法称为init...,除非它们是初始化程序

  • 通常要避免传递

  • 元编程破坏了编译器进行健全性检查的能力。避免它。

答案 1 :(得分:1)

编译器不知道如何处理原始指针。您应该明确说明您期望的内存管理策略类型。在你的情况下,它可能像

LWPagerContent * __strong *contentPtr = (LWPagerContent * __strong *)[[args objectAtIndex:1] pointerValue];

类型是“指向LWPagerContent的强指针”。从现在起*contentPtr将被ARC视为强指针。

答案 2 :(得分:0)

你试过了吗?

NSValue* contentPtrPtr = [args objectAtIndex:1];
LWPagerContent** contentPtr = [contentPtrPtr pointerValue];