我完全迷失了我的代码所发生的事情。这让我想到了&使用Array的线程安全概念清楚。是NSMutableArray还是NSMutableDictionary线程安全吗?
虽然我的代码正在执行,但是MainArray的值得到了更改,尽管已经添加到Array中。
请尝试执行此代码,在您的系统上非常容易。我无法摆脱此陷阱。
它是返回Array的函数。 我要做的是: - (数组)(主阵列) - >(词典),键值(主阵列中的多个词典) ----->上面的字典中有9个数组。
这是我为Array.But开发的结构,甚至在
之前#define TILE_ROWS 3
#define TILE_COLUMNS 3
#define TILE_COUNT (TILE_ROWS * TILE_COLUMNS)
-(NSArray *)FillDataInArray:(int)counter
{
NSMutableArray *temprecord = [[NSMutableArray alloc] init];
for(int i = 0; i <counter;i++)
{
if([temprecord count]<=TILE_COUNT)
{
NSMutableDictionary *d1 = [[NSMutableDictionary alloc]init];
[d1 setValue:[NSString stringWithFormat:@"%d/2011",i+1] forKey:@"serial_data"];
[d1 setValue:@"Friday 13 Sep 12:00 AM" forKey:@"date_data"];
[d1 setValue:@"Description Details " forKey:@"details_data"];
[d1 setValue:@"Subject Line" forKey:@"subject_data"];
[temprecord addObject:d1];
d1= nil;
[d1 release];
if([temprecord count]==TILE_COUNT)
{
NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:temprecord,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
[self.casesListArray addObject:holderKey];
[holderKey release];
holderKey =nil;
[temprecord removeAllObjects];
}
}
else {
[temprecord removeAllObjects];
NSMutableDictionary *d1 = [[NSMutableDictionary alloc]init];
[d1 setValue:[NSString stringWithFormat:@"%d/2011",i+1] forKey:@"serial_data"];
[d1 setValue:@"Friday 13 Sep 12:00 AM" forKey:@"date_data"];
[d1 setValue:@"Description Details " forKey:@"details_data"];
[d1 setValue:@"Subject Line" forKey:@"subject_data"];
[temprecord addObject:d1];
d1= nil;
[d1 release];
}
}
return temprecord;
[temprecord release];
}
此代码有什么问题?每次在Array中有9条记录时,它只是替换整个Array值而不是仅替换特定的键值。
答案 0 :(得分:1)
首先,Cocoa不可变集合是线程安全的。他们的可变对应物不线程安全。使代码线程安全取决于应用程序的设计。多线程程序中的一个好习惯是使用尽可能多的不可变数据。
其次,在:
NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:temprecord,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
[self.casesListArray addObject:holderKey];
[holderKey release];
holderKey =nil;
[temprecord removeAllObjects];
您有以下内容:
temprecord
指向一个可变数组holderKey
的可变字典,其中包含一个对象,即与上面相同的temprecord
self.casesListArray
holderKey
,因为它已在上一步中添加到数组中而未被解除分配temprecord
删除所有对象。由于temprecord
与holderKey
中的数组相同,因此它也是该字典中的空数组。由于holderKey
被添加到self.casesListArray
,因此相应的数组元素是相同的字典,具有相同的(现在为空)数组。由于在执行该方法期间将-removeAllObjects
发送到temprecord
,您可能希望存储数组当前值的副本(可变或不可变):
NSMutableArray *tempRecordCopy = [temprecord mutableCopy];
NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:tempRecordCopy,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
[tempRecordCopy release];
我不确定你是否需要数组是否可变。如果不这样做,请将其更改为NSArray
和-copy
,并且您将拥有不可变副本。
最后,您使用的是奇怪的模式,导致托管内存设置中的内存泄漏。例如,在:
d1= nil;
[d1 release];
由于您将nil
分配给d1
,因此以下指令[d1 release]
实际上是无操作。这意味着d1
不再指向原始对象,并且此对象尚未释放。不要这样做。代替:
[d1 release];
在大多数情况下已经足够了,如果你真的需要nil
变量,请在发布后执行:
[d1 release];
d1 = nil;
修改:进一步说明:在:
return temprecord;
[temprecord release];
temprecord
未被释放,因为该方法在返回时结束。释放temprecord
的尝试是无法访问的代码,永远不会被执行。你想要这个:
return [temprecord autorelease];
另一个编辑:请注意,-setObject:forKey:
是将对象添加到字典的规范方法。您正在使用-setValue:forKey:
,这是一种KVC方法,在字典上使用时具有特殊的行为。除非您熟悉KVC,否则我建议您使用-setObject:forKey:
。