使用for循环中的数据填充NSMutableArray

时间:2011-06-26 20:03:44

标签: iphone objective-c ios

我正在尝试执行与NSMutableArray相关的简单代码,而且我已经碰壁了。这是我的代码:

NSMutableArray *newArray = [[[NSMutableArray alloc] initWithCapacity:4] retain];
NSArray *existingSection2 = [[NSArray alloc] initWithObjects:@"S2 Item1",@"S2 Item2",@"S2 Item3",@"S2 Item4",nil];

for (int i=0; i<[existingSection2 count]; i++) {
    NSString *val = [[NSString alloc] initWithString:[existingSection2 objectAtIndex:i]];
    [newArray addObject:val];
    NSLog(@"val %i is %@ new array now contains: %@",i,val,[newArray objectAtIndex:i]);
    NSLog(@"new array description: ",[newArray description]);
}
NSLog(@"what's in newArray: ",[newArray objectAtIndex:0]);

据我了解,这就是我正在做的事情:
1)分配一个名为newArray的新NSMutableArray,容量为4
2)使用四个NSString值分配名为existingSection2的NSArray 3)迭代现有第2节中的四个NSStrings中的每一个 3a)在位置i
处分配名为val的NSString和existingSection2数组的内容 3b)在下一个可用位置添加val到newArray
3c)记录一些用于调试的东西 4)记录newArray的最终内容以进行调试

此代码位于application:didFinishLaunchingWithOptions:,但这是我在模拟器中启动时控制台窗口显示的内容:

2011-06-26 15:50:48.203 ArrayTest[14936:207] val 0 is S2 Item1 new array now contains: S2 Item1
2011-06-26 15:50:48.205 ArrayTest[14936:207] new array description: 
2011-06-26 15:50:48.205 ArrayTest[14936:207] val 1 is S2 Item2 new array now contains: S2 Item2
2011-06-26 15:50:48.205 ArrayTest[14936:207] new array description: 
2011-06-26 15:50:48.206 ArrayTest[14936:207] val 2 is S2 Item3 new array now contains: S2 Item3
2011-06-26 15:50:48.206 ArrayTest[14936:207] new array description: 
2011-06-26 15:50:48.206 ArrayTest[14936:207] val 3 is S2 Item4 new array now contains: S2 Item4
2011-06-26 15:50:48.206 ArrayTest[14936:207] new array description: 
2011-06-26 15:50:48.207 ArrayTest[14936:207] what's in newArray: 

我不明白为什么我没有用这四个新的NSString对象填充newArray!我一直在寻找类似的问题,但答案似乎都与初始化NSMutableArray有关,我相信我做得正确。

感谢您的帮助!

3 个答案:

答案 0 :(得分:9)

我有一些问题需要指出,我希望你能从中学到一些东西。我们走了......

内存管理

使用allocnewcopy(例如[[NSArray alloc] ...][[NSString alloc] ...])创建对象时,会返回+1并保留计数。这意味着您“拥有”该对象,并负责稍后通过调用release(您目前没有在您的代码中执行)来释放它。例如,如果您使用[NSArray arrayWith...],则不会获得+1保留计数(您将获得一个自动释放的对象),如果您希望它保持不变,则必须调用retain

那就是说,当你做的时候

NSMutableArray *newArray = [[[NSMutableArray alloc] initWithCapacity:4] retain];

alloc为您提供+1保留计数,然后您再次呼叫retain!这是不必要的。

但是,由于您不需要在此函数之外使用数组或字符串,因此根本不需要保留它们,因此您只需使用:

NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:4];

NSString *val = [NSString stringWithString:[existingSection2 objectAtIndex:i]];
// or even more simply
NSString *val = [existingSection2 objectAtIndex:i];

有关详细信息和最佳做法,请阅读Memory Management Programming Guide

环/迭代

您在[existingSection2 count]循环中使用i++for的方法有效,但这不是最佳方法。 Obj-C有所谓的Fast Enumeration,它更简单,我希望你能用它:

for (NSString *val in existingSection2) {
    //...
}

NSLog和格式字符串

NSLog函数通过采用格式字符串(包含整数的printf和Obj-C对象的%d等格式说明符)起作用(类似于C的%@) ),然后是为说明符输入的参数列表。

使用时

NSLog(@"new array description: ",[newArray description]);

您只会记录字符串“new array description:”,因为您没有与描述相对应的格式说明符。相反,你应该这样做:

NSLog(@"new array description: %@", [newArray description]);
// or even more simply
NSLog(@"new array description: %@", newArray);

还可以在String Format Specifiers上提供更多可用于NSLog的信息。

总体

以下是使用上述技术重写代码。

NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:4];
NSArray *existingSection2 = [NSArray arrayWithObjects:@"S2 Item1",@"S2 Item2",@"S2 Item3",@"S2 Item4",nil];

for (NSString *val in existingSection2) {
    [newArray addObject:val];
    NSLog(@"value is %@",val);
    NSLog(@"new array contains: %@", newArray);
}
NSLog(@"what's in newArray: %@",[newArray objectAtIndex:0]);

答案 1 :(得分:1)

打印数组描述时,需要在格式字符串中添加%@

此外,您无需显式调用description,因为在使用%@打印对象时会自动调用它,如:

NSLog(@"New array is: %@", newArray);

答案 2 :(得分:1)

您遇到了日志记录问题:

NSLog(@"new array description: ",[newArray description]);

应该是

NSLog(@"new array description: %@",[newArray description]);

奖金帮助:

NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:4];  // fix memory leak
NSArray *existingSection2 = [[NSArray alloc] initWithObjects:@"S2 Item1",@"S2 Item2",@"S2 Item3",@"S2 Item4",nil];

for (id section in existingSection2) // fast enumeration
{
    NSString *val = [[NSString alloc] initWithString:[existingSection2 objectAtIndex:i]];
    [newArray addObject:val];
    NSLog(@"val %i is %@ new array now contains: %@",i,val,[newArray objectAtIndex:i]);
    NSLog(@"new array description: %@",[newArray description]);
    [val release]; // fix memory leak
}

NSLog(@"what's in newArray: %@",[newArray objectAtIndex:0]);