【问题标题】:IOS - Create new object instances through a loop with ARCIOS - 通过使用 ARC 的循环创建新对象实例
【发布时间】:2012-09-20 07:36:42
【问题描述】:

基本上,我的问题是我试图通过循环创建 3 个 UIView 实例。我正在使用 ARC,我真的不知道我想做的事情是否可行。这是我目前拥有的代码:

NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"RoomView"
                                                  owner:self
                                                options:nil];
NSMutableArray *roomViews = [[NSMutableArray alloc] initWithCapacity:[gtb.rooms count]];

for (i = 0; i < [gtb.rooms count]; i++)
{
    RoomView *rcv = [[RoomView alloc] init];
    NSDictionary *room = [gtb.rooms objectAtIndex:i];
    rcv = [nibViews objectAtIndex:0];
    NSLog(@"Start rcv = %@", rcv);
    rcv.roomNumber.text = [NSString stringWithFormat:@"Chambre %d", i + 1];
    rcv.roomType.text = [room objectForKey:@"roomType"];
    [rcv setFrame:CGRectMake(0, sizeOfContent, rcv.frame.size.width, rcv.frame.size.height)];
    sizeOfContent += rcv.frame.size.height;
    [roomViews addObject:rcv];
    NSLog(@"End rcv = %@", rcv);
}

for (i = 0; i < [gtb.rooms count]; i++)
    NSLog(@"Room #%i : %@", i, [roomViews objectAtIndex:i]);

这就是我在日志中的内容:

2012-09-20 10:15:00.287 AppName[2792:707] Start rcv = <RoomView: 0x148570; frame = (0 0; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.289 AppName[2792:707] End rcv = <RoomView: 0x148570; frame = (0 420; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.312 AppName[2792:707] Start rcv = <RoomView: 0x148570; frame = (0 420; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.314 AppName[2792:707] End rcv = <RoomView: 0x148570; frame = (0 527; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.316 AppName[2792:707] Start rcv = <RoomView: 0x148570; frame = (0 527; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.317 AppName[2792:707] End rcv = <RoomView: 0x148570; frame = (0 634; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.319 AppName[2792:707] Room #0 : <RoomView: 0x148570; frame = (0 634; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.323 AppName[2792:707] Room #1 : <RoomView: 0x148570; frame = (0 634; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>
2012-09-20 10:15:00.325 AppName[2792:707] Room #2 : <RoomView: 0x148570; frame = (0 634; 320 107); autoresize = W+H; layer = <CALayer: 0x148510>>

我知道如果我没有使用 ARC,我应该在循环末尾放置类似 [rcv autoRelease] 的内容,但使用 ARC,我不能。

有什么办法可以解决这个问题,还是我必须为此文件禁用 ARC?

感谢您的帮助!

【问题讨论】:

  • 我没有看到您在循环中创建任何 UIView 实例。这些实例显然是在您调用loadNibNamed: 时创建的。他们只是从nibViews 传递到roomViews
  • 我已经编辑了我的帖子。但似乎当我将对象添加到我的数组时,所有对象都采用最后一个对象的属性。
  • 哦,那是因为你打电话给[nibViews objectAtIndex:0]而不是[nibViews objectAtIndex:i]
  • 另外,你用NSDictionaryroom做什么?好像从来没用过。
  • 我不能真正调用[nibViews objectAtIndex:i],因为我在数组中只有一个对象。也许我理解错了,但我想为同一个视图创建 3 个不同的实例。使用NSDictionary *room,我填充了一些视图变量。我没有在代码中显示它,因为我认为它没有必要。

标签: iphone objective-c ios automatic-ref-counting instance


【解决方案1】:

你需要替换这一行:

rcv = [nibViews objectAtIndex:0];

有了这个:

rcv = [[nibViews objectAtIndex:0] copy];

因为如果不是,您只是在访问同一个视图对象,而不是从它复制的新对象(未复制强引用)。

另一方面,ARC 在这件事上没有影响。如果没有 ARC,你也会遇到同样的问题。使用 ARC,您无需编写发布/自动发布等。

【讨论】:

  • 收到此错误:` *** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[RoomView copyWithZone:]:无法识别的选择器已发送到实例 0x24b1c0'`
  • 我的错,UIViews 可能没有实现复制方法。您应该在自定义类中覆盖它,以复制您感兴趣的值。另一种(低效)方法是每次在循环内加载 nib,调用 [[[NSBundle mainBundle] loadNibNamed:@"RoomView" owner:self 选项: nil] objectAtIndex:0]
  • 这种低效的方式适用于我的情况。为什么说效率低?
  • 因为您可能一直通过加载相同的内容从磁盘读取。它比复制内存中的对象要慢。
【解决方案2】:

使用 ARC,系统会为您调用自动释放功能。您无需担心。

【讨论】:

    【解决方案3】:

    根据内存管理规则,你只需要释放你 alloc-init 或复制的对象。在这里,您没有同时使用 RoomView *rcv。 所以即使你的代码是not ARC enabled,你也不需要释放或自动释放它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-27
      • 2014-06-28
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      相关资源
      最近更新 更多