对象的NSMutableArray行为不端

时间:2010-04-22 12:42:56

标签: iphone objective-c xcode debugging nsmutablearray

我希望有人了解我的NSMutableArray会发生什么。

我从数据库中读取记录a,b,c,d,将字段加载到对象中,并将对象添加到数组中。为此,我将记录读入该对象的实例(tmpEvent),并将Object添加到目标数组(NSMutableArray myArray)。

代码如下:

for (condition) {
     tmpEvent.field1 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
     tmpEvent.field2 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 1)];
     tmpEvent.field3 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 2)];

     NSLog(@"myArray: adding %@", tmpEvent.field1);
     [myArray addObject:tmpEvent];
}

NSLog显示

 myArray: adding a
 myArray: adding b
 myArray: adding c
 myArray: adding d

随后我枚举数组(可以使用相同或不同的方法):

for (myObject *records in myArray) {
    NSLog(@"iEvents  value %@", records.field1);
}

NSLog现在显示:

 myArray value d
 myArray value d
 myArray value d
 myArray value d
一个谜......有什么想法吗?

1 个答案:

答案 0 :(得分:3)

您需要为每个事件分配一个新的“iEvent”。 tmpEvent.field1指向内存中每个后续添加的相同位置,因此您正在修改已存储在数组中的对象。 NSArray不会创建对象的新副本,只存储其指针/地址。

一个修复:

[myArray addObject:[tmpEvent copy]];

这假设iEvent类的成员符合NSCopy。

另一种方法是为要存储的每个事件分配一个新的tmpEvent。

问题:但这是否意味着当我释放我的数组时,我需要枚举并“手动”再次释放对象?

答案:在将对象添加到数组后,应该将对象发送给数组,因为数组会向其发送保留。处理数组时,所有对象都会发送一个释放,因此您不必这样做。见下文......

尝试使用alloc选项,因为符合NSCopying要求你分配一个对象:

for(condition){     tmpEvent = [[TmpEvent alloc] init]; //或者它被初始化

 tmpEvent.field1 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
 tmpEvent.field2 = ...

 [myArray addObject:tmpEvent];

// NSArray保留您添加的对象。      [tmpEvent release]; }

----符合NSCopy --- 1.类必须继承自NSCopying @interface TmpEvent:NSObject ...

  1. 实施 - (id)copyWithZone:(NSZone *)zone

    • (id)copyWithZone:(NSZone *)zone { TmpEvent * copyOfMyself = [[TmpEvent alloc] init]; copyOfMyself.field1 = [self.field1 copy]; ......等等。

    返回copyOfMyself; }