保留Objective-C中的计数和工厂方法

时间:2011-09-30 11:58:15

标签: iphone objective-c

我之前一直在这个论坛中找到创建工厂函数的最佳方法,以便从笔尖构建自定义视图(here是我以前的帖子)

我现在使用以下代码:

+ (LoadingV *)loadingViewCopyFromNib 
{   
    LoadingV *view = nil;   
    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"LoadingV" owner:self options:nil];
    view = (LoadingV*)[nibViews objectAtIndex: 0];

    // Setting up properties
    CGRect frm = view.progress.frame;
    frm.size.width *=1.5;
    frm.size.height *=1.5;
    view.progress.frame = frm;
    view.waitLbl.text = NSLocalizedString(@"Please wait", @"");     
    return view;    <------- warning is here
}

// In .h file
...
LoadingView* loadV;
@property (nonatomic, retain) LoadingView* loadV;

// in .m file
@synthesize loadV;
...
self.loadV = [LoadingV loadingViewCopyFromNib];

当我构建和分析时,我收到有关工厂功能的以下警告:

  

/LPAPP/Classes/LoadingV.m:34:5返回+0保留计数的对象   调用者预期+1(拥有)保留计数

为什么会这样?我理解在函数中分配的局部变量不会超出其范围,除非它们被保留并自动释放。但在我的情况下,我不是创建一个新对象,只是返回对现有对象的引用。那我为什么要收到警告呢?这样做是否安全:)

干杯 AF

2 个答案:

答案 0 :(得分:1)

虽然迈克是对的,但警告却有完全不同的原因。 您的方法名称包含“copy”,它被解释为返回+1保留计数(类似于alloc,init)。请记住,一旦转换到ARC,这可能会导致问题!

答案 1 :(得分:0)

对于像NSArray这样的集合类,objectAtIndex:和其他类似访问器返回的引用不能保证在取消分配父容器时保持有效。换句话说,objectAtIndex:不会返回自动释放的对象。

这意味着一旦它来自的数组被释放,你返回的指针可能最终变为无效。

要解决此问题,请在return语句中使用retain + autorelease

return [[view retain] autorelease];

<强>更新

我无法在我的Xcode版本中重现此警告。但也许马丁是正确的,你正在使用的GCC / clang版本正在解释'副本'。最新的Xcode和gcc / clang编译器不会出现此警告,规则是只有“copy”或“mutableCopy”的前缀被解释为返回+1保留对象。 / p>