1

我正在转换为ARC,并且无法找到任何方式来摆脱此编译器错误而不会破坏代码。将一个指针传递给NSArray中的一个对象,使用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在其他帖子中推荐,但似乎没有任何工作。任何建议不胜感激。

+0

我们是否假设您不能只更改initArticlePagerContent:? – 2013-02-12 20:51:22

+0

名称'init ...'在ARC中有特殊含义。这真的是一个初始化程序吗?如果没有,请不要使用'init'开始它的名字。 – matt 2013-02-12 20:52:12

+0

请更准确地说错误发生在哪一行以及您尝试过什么。 – matt 2013-02-12 20:52:28

回答

1

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

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

的类型是“指向一个强大的指针LWPagerContent”。从现在开始,*contentPtr将被视为ARC的强大指针。

+0

感谢这正是我所寻找的 – user2066193 2013-02-12 22:03:40

+0

不是真的;它“有效”,但它不是很好的设计。例如,当你从辅助线程到主要异步线程进行调用时,它会出现繁荣,或者至少需要一些重构。 – bbum 2013-02-13 00:18:47

0

你试过:

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

使用块去主线程,消除了元编程由-performSelector暗示:打电话。

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

I.e.

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

一些注意事项:

  • 方法不应该叫init...,除非它们是初始化

  • 传递通过引用通常是要避免

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

相关问题