【问题标题】:Objective-c NSMutableArray of Objects retainObjective-c NSMutableArray of Objects 保留
【发布时间】:2012-03-01 09:08:09
【问题描述】:

我就是不明白!我有自定义类“Word”,我还通过几个步骤生成了 Word-class-objects 的 NSMutableArray:

  1. words = [NSMutableArray 数组];
  2. 对于 i = 0 到 8
  3. word = alloc+init;
  4. [words addObject: word];
  5. [文字发布];

然后我将单词实例传递给另一个类的设置器:

someInstance.words = words;

如果单词是非原子的,则保留属性。我这样声明 setWords 方法:

-(void)setWords:(NSMutableArray *)w {
    [w retain];
    [words release];
    words = w;
}

当单词作为“w”变量进入方法时,它是一个对象数组,但是当我保留它并分配给我的旧值时,我的单词变量变成一个 NSMUtableArray 并且它的计数等于 w.count,但是数组的项0x0。 “=”运算符不复制数组项,我该如何解决?请帮忙,我是objective-c的新手。 我只用一种方法实例化 Word,我应该实现无参数的 init 方法吗?

-(id)initWithId:(int)Id Word:(NSString *)Word Card:(int)Card {
    self.id = Id;
    self.word = Word;
    self.card = Card;
    return self;
}

我生成 NSMutableArray 的循环:

Card *card = [[Card alloc] initWithId:[s intForColumn:@"id"] Type:[s intForColumn:@"type"] Used:[s intForColumn:@"used"]];
s = [db executeQueryWithFormat:@"SELECT w.id as id, word, card FROM word as w INNER JOIN card as c ON w.card=c.id WHERE c.id=%i ORDER BY w.id, RANDOM()", card.id];
while ([s next]) {
    Word *word = [[Word alloc] initWithId:[s intForColumn:@"id"] Word:[s stringForColumn:@"word"] Card:[s intForColumn:@"card"]];
    [card.words addObject:word];
    [word release];
}

【问题讨论】:

  • 为了理解你可以看一下截图我因为名声小没能插入帖子中:i.stack.imgur.com/UheIk.png
  • 向我们展示您的子类初始化方法。
  • 另一个想法是在你的setter方法中使用words = [w mutableCopy]
  • 您能否在将它传递给 setter 之前添加用于创建此数组的确切代码?
  • @Rog:并非完全不相关;它仍然记录了 setter 的行为。

标签: objective-c ios4 nsmutablearray retain


【解决方案1】:

您的代码存在许多问题。

  • 你需要遵循标准的初始化模式,调用super的指定初始化器并检查返回值。

  • 该方法应命名为 initWithId:word:card:(即大小写错误,因此 StackOverflow 上的颜色也很愚蠢)。

  • 如果您的 setter/getter 只遵循标准模式,则无需实现自定义 setter/getter。使用@property 和@synthesize。

  • (来自您的屏幕截图)您真的不想直接从您的设置器触发 UI 更新。一般来说,无论如何。通常,您希望视图层通过控件触发模型的更新,并且在模型完全更新后,让视图层知道它应该重新加载。

  • 虽然您提到您正在实例化一个 NSMutableArray 实例,但您并没有在代码中显示这一点。在添加Word 实例时是否真的设置了card.words

显示 -initWithId:card:type:used:(注意我更正了案例)方法的实现。

即最好有类似的东西:

 words = [NSMutableArray new]; // Or, if ARC, [NSMutableArray array];

好的——下一个...

  • while() 循环之前放置一个assert(card.words);...如果没有设置words,它会爆炸。

  • 确保card 不为零(没有理由不应该,但是...当明显的东西看起来正确时,接下来检查真的明显的东西)

关于 -reloadData 的评论更多的是你想要reloadData 在任何首先触发加载的情况下。想象一下在更新整个 UI 之前加载几种不同类型的数据的情况;也许必须重新加载表格视图一些其他的东西需要围绕它进行更新。通过将 reloadData 移出 setter,它 (a) 使 setter 变得简单且不令人惊讶,而 (b) 使重构 UI 层变得更容易,以便可以同时进行多 UI 元素更新。

(另外——请不要对我的 cmets 编码风格过于苛刻......不是故意的...... Obj-C 编码有一些微妙但通用的模式。如果你学习并使用它们,它会让你的生活更轻松。我们曾经都是 Obj-C 的新手。只是我们中的一些人是新手,而你们中的其他人甚至还没有出生。;)。

【讨论】:

  • -(id)initWithId:(int)i type:(int)t used:(int)u { self.id = i; self.type = t; self.used = 你; self.words = [NSMutableArray 数组];回归自我; }
  • 1.我修好了 2. 好的,我的错误,更正了 3. 但是我也想执行 [tableView reloadData] 方法 4. tableView 是 UITableView,words 是我填充表格单元格的数据,当我调用 reloadData 时不是必须的吗更新数据源? 5.看上一条评论
  • 我让我的分配工作刚刚删除了@synthesize words 语句并添加了 NSMutableArray *words_,但现在我无法使用新数据源更新我的 tablwview,即使 [tableView reloadData] 不工作 =(跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多