Ios4 如果数组是线程安全的,那么这个函数有什么问题?

Ios4 如果数组是线程安全的,那么这个函数有什么问题?,ios4,iphone-sdk-3.0,thread-safety,nsmutablearray,nsmutabledictionary,Ios4,Iphone Sdk 3.0,Thread Safety,Nsmutablearray,Nsmutabledictionary,我对代码中发生的事情完全迷茫了。这让我思考并弄清楚数组的线程安全概念。NSMutableArray或NSMutableDictionary是否线程安全 当我的代码正在执行时,MainArray的值会发生更改,尽管已添加到数组中 请尝试在您的系统上执行此代码,这非常简单。我无法摆脱此陷阱 它是返回数组的函数。 我想做的是: -(阵列)(主阵列) -->(字典)键值(主数组中有多个字典) ----->上面的字典中有9个数组 这是我为Array开发的结构。但甚至在之前 #define TILE_ROW

我对代码中发生的事情完全迷茫了。这让我思考并弄清楚数组的线程安全概念。NSMutableArray或NSMutableDictionary是否线程安全

当我的代码正在执行时,MainArray的值会发生更改,尽管已添加到数组中

请尝试在您的系统上执行此代码,这非常简单。我无法摆脱此陷阱

它是返回数组的函数。 我想做的是: -(阵列)(主阵列) -->(字典)键值(主数组中有多个字典) ----->上面的字典中有9个数组

这是我为Array开发的结构。但甚至在之前

#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];
}
#定义平铺第3行
#定义TILE_列3
#定义平铺计数(平铺行*平铺列)
-(NSArray*)FillDataInArray:(int)计数器
{
NSMutableArray*temprecord=[[NSMutableArray alloc]init];

对于(int i=0;i首先,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.casesListaray
  • 您释放了
    holderKey
    ,它不会被释放,因为它是在上一步添加到数组中的
  • temprecord
    中删除所有对象。由于
    temprecord
    holderKey
    中的数组相同,因此该字典中的数组也将是空数组。由于
    holderKey
    已添加到
    self.casesListaray
    ,因此相应的数组元素是相同的字典,具有相同的属性(现在为空)数组
由于在执行该方法期间将
-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:

+1用于格式化答案。完美,…我在将temprecord添加到NSDictionary时简单地添加了[temprecord copy],效果很好。对于MM,我一直返回[temprecord autorelease];