Objective-c NSMutableArray 对象保留
我就是听不懂!我有自定义类“Word”,我还通过几个步骤生成了 Word 类对象的 NSMutableArray:
- words = [NSMutableArray array];
- 对于 i = 0 到 8
- 字 = alloc+init;
- [单词addObject:单词];
- [词发布];
然后我将单词实例传递给另一个类的设置器:
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 just can't get it! I have custom class "Word" also I generate NSMutableArray of Word-class-objects in few steps:
- words = [NSMutableArray array];
- for i = 0 to 8
- word = alloc+init;
- [words addObject: word];
- [word release];
Then I pass words instance to setter of another class:
someInstance.words = words;
Where words is nonatomic, retain property. I declare setWords method like this:
-(void)setWords:(NSMutableArray *)w {
[w retain];
[words release];
words = w;
}
When words come to method as "w" variable it is an array of object but when I retain it and assign to my old value my words variable becomes an NSMUtableArray and it count is equal to w.count, but items of array 0x0. The "=" operator does not copy items of array, how can I fix it? Please help, I am a newbie in objective-c.
I instanciate Word only with one method, shoud I implement parameterless init method?
-(id)initWithId:(int)Id Word:(NSString *)Word Card:(int)Card {
self.id = Id;
self.word = Word;
self.card = Card;
return self;
}
The cycle where I generate my 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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码存在许多问题。
您需要遵循调用 super 的指定初始化程序并检查返回值的标准初始化模式。
该方法应命名为
initWithId:word:card:
(即大小写错误,因此 StackOverflow 上的颜色甚至是愚蠢的)。如果您的 setter/getter 只需遵循标准模式,则无需实现自定义 setter/getter。使用 @property 和 @synthesize。
(从你的屏幕截图来看)你真的不想从你的设置器直接触发 UI 更新。一般来说,无论如何。一般来说,您希望视图层通过控件触发模型的更新,一旦模型完全更新,然后让视图层知道它应该重新加载。
虽然您提到您正在实例化 NSMutableArray 实例,但您没有在代码中显示这一点。当您添加
Word
实例时,card.words
真的设置了吗?显示 -initWithId:card:type:used: (注意我更正了大小写)方法的实现。
即最好有类似这样的内容:
OK -- next...
在
while()
循环之前放置一个assert(card.words);
...如果未设置words
,则会崩溃。确保
card
非零(没有理由不应该但是......当明显的东西看起来正确时,你检查真正明显的东西接下来的东西)关于 -reloadData 的评论更多的是你想要的
reloadData
在任何首先触发加载的地方。想象一下这样的情况:您在更新整个 UI 之前加载几种不同类型的数据;也许表视图必须重新加载并且需要围绕它更新一些其他内容。通过将reloadData
移出 setter,它 (a) 使 setter 变得简单且不足为奇,同时 (b) 使重构 UI 层变得更容易,以便可以同时完成多个 UI 元素更新。(另外,请不要严厉地对待我对编码风格的评论……并不是故意的……Obj-C 编码有一些微妙但通用的模式。如果你学习它们并使用它们,它会让你的生活变得更轻松。我们曾经都是 Obj-C 的新手,只是我们中的一些人还没有出生。
There are a number of problems w/your code.
you need to follow the standard initialization pattern of calling super's designated initializer and checking the return value.
That method should be named
initWithId:word:card:
(i.e. case is wrong, hence the goofy coloring on StackOverflow, even).There is no need to implement a custom setter/getter if your setter/getter just follow the standard pattern. Use an @property and @synthesize.
(from your screenshot) you really don't want to be directly triggering UI updates from your setter. Generally, anyway. Generally, you want your view layer to trigger an update of your model through the control and, once the model is fully updated, then let the view layer know it should reload.
While you mention that you are instantiating an NSMutableArray instance, you don't show that in your code. Is
card.words
really set when you are addingWord
instances?Show the -initWithId:card:type:used: (note I corrected the case) method's implementation.
I.e. it better had have something like:
OK -- next...
put an
assert(card.words);
before yourwhile()
loop... that'll blow up ifwords
isn't set.make sure that the
card
is non-nil (no reason why it shouldn't but... when the obvious stuff looks right, you check the really obvious stuff next)The comment about -reloadData is more that you would want to
reloadData
in whatever triggers the loading in the first place. Imagine a situation where you are loading several different kinds of data prior to updating the whole UI; maybe the table view has to be reloaded and some other stuff needs to be updated around it. By moving thereloadData
out of the setter it (a) makes the setter simple and non-surprising while (b) makes it easier to refactor your UI layer such that multi-UI element updating can be done simultaneously.(Also -- please don't take my comments about coding style harshly... not meant to be... there are some subtle, but universal patterns to Obj-C coding. If you learn them and use them, it'll make your life a lot easier. We were all new to Obj-C once. Just that some of us were new to it while others of your weren't even born yet. ;).