开发者

If array is thread safe, what the issue with this function?

I am totally lost with the things that is happening with my code.It make me to think & get clear with Array's thread Safe concept. Is NSMutableArray OR NSMutableDictionary Thread Safe ?

While my code is under execution, the values for the MainArray get's changes although, that has been added to Array.

Please try to execute this code, onyour system its very much easy.I am not able to get out of this Trap.

It is the function where it is returning Array. What I am Looking to do is : -(Array) (Main Array) -->(Dictionary) with Key Value (Multiple Dictionary in Main Array) -----> Above dictionary has 9 Arrays in it.

This is the structure I am developing for Array.But even before

#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]<开发者_C百科=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];
}

What is the problem with this Code ? Every time there are 9 records in Array, it just replaces the whole Array value instead of just for specific key Value.


Firstly, Cocoa immutable collections are thread-safe. Their mutable counterparts are not thread-safe. Making your code thread-safe depends on the design of your application. A good practice in a multithreaded program is to use as many immutable data as possible.

Secondly, in:

NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:temprecord,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
[self.casesListArray addObject:holderKey];
[holderKey release];
holderKey =nil;
[temprecord removeAllObjects]; 

you have the following:

  • temprecord points to a mutable array
  • you create a mutable dictionary called holderKey that contains a single object, namely the same temprecord as above
  • you add this mutable dictionary to self.casesListArray
  • you release holderKey, which doesn’t get deallocated because it was added to an array in the previous step
  • you remove all objects from temprecord. Since temprecord is the same array as the one in holderKey, it’ll be an empty array in that dictionary, too. Since holderKey was added to self.casesListArray, the corresponding array element is the same dictionary, with the same (now empty) array.

Since you send -removeAllObjects to temprecord during the execution of that method, you probably want to store a copy (either mutable or immutable) of the current values of the array instead:

NSMutableArray *tempRecordCopy = [temprecord mutableCopy];

NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:tempRecordCopy,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];

[tempRecordCopy release];

I’m not really sure whether you need the array to be mutable. If you don’t, change that to NSArray and -copy and you’ll have an immutable copy.

Lastly, you’re using an odd pattern that results in memory leaks in a managed memory setting. For example, in:

d1= nil;
[d1 release];

since you’re assigning nil to d1, the following instruction, [d1 release], is effectively a no-operation. This means that d1 doesn’t point to the original object anymore, and this object hasn’t been released. Don’t do this. Instead:

[d1 release];

is enough in most cases and, if you truly need to nil out the variable, do it after release:

[d1 release];
d1 = nil;

Edit: A further note: in:

return temprecord;
[temprecord release];

temprecord doesn’t get released because the method ends upon returning. That attempt at releasing temprecord is unreachable code and never gets executed. You want this instead:

return [temprecord autorelease];

Another edit: Note that -setObject:forKey: is the canonical method for adding objects to a dictionary. You’re using -setValue:forKey:, which is a KVC method that has a peculiar behaviour when used on dictionaries. Unless you’re familiar with KVC, I suggest you use -setObject:forKey:.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜