Array of arrays

Discussion in 'iOS Programming' started by beesbane, Nov 9, 2010.

  1. beesbane macrumors newbie

    Joined:
    Oct 16, 2010
    #1
    I'm trying to build an array of arrays with data from a plist. I've built a normal working array of arrays:

    Code:
    listOfItems = [[NSMutableArray alloc] init];
    
    NSArray *countriesE = [NSArray arrayWithObjects:@"England", nil];
    	NSArray *sortedArrayE = [countriesE sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    	NSDictionary *countriesSE = [NSDictionary dictionaryWithObject:sortedArrayE forKey:@"Countries"];
    
    	NSArray *countriesF = [NSArray arrayWithObjects:@"Finland", @"France", nil];
    	NSArray *sortedArrayF = [countriesF sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    	NSDictionary *countriesSF = [NSDictionary dictionaryWithObject:sortedArrayF forKey:@"Countries"];
    
    [listOfItems addObject:countriesSE];
    [listOfItems addObject:countriesSF];
    
    I can call that and it returns correctly. But when I do it with the plist arrays, it just doesn't work right. I can make one array display correctly, but when I try to put that into another array, the build succeeds, but the app instantly crashes.

    In the following example, when I return only one of the tableDataSource(s) it works, but load them into an array, and it fails.

    Code:
    everythingArray = [[NSMutableArray alloc] init];
    
    NSArray *tempArrayC = [[NSArray alloc] init];
    	self.tableDataSourceC = tempArrayC;
    	NSArray *sortedArrayC = [tempArrayC sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    	
    	[sortedArrayC release];
    		
    	DrillDownAppAppDelegate *AppDelegateC = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    	self.tableDataSourceC = [AppDelegateC.data objectForKey:@"C"];
    	
    	//Initialize our table data source
    	NSArray *tempArrayJ = [[NSArray alloc] init];
    	self.tableDataSourceJ = tempArrayJ;
    	NSArray *sortedArrayJ = [tempArrayJ sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    	
    	[sortedArrayJ release];
    	
    	DrillDownAppAppDelegate *AppDelegateJ = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    	self.tableDataSourceJ = [AppDelegateJ.data objectForKey:@"J"];
    		
    	[everythingArray addObject:countriesSC];
    	//[everythingArray addObject:tableDataSourceJ];
    
    Can someone tell me where I've gone wrong? Debugger says "-[__NSCFDictionary caseInsensitiveCompare:]: unrecognized selector sent to instance 0x5f4a7b0".
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    At this point, tableDataSourceC is an empty array.
    Code:
    	NSArray *sortedArrayC = [tempArrayC sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    
    You've sorted an empty array. Why?

    Code:
    	[sortedArrayC release];
    
    You've now released the sorted empty array, but you don't own it.

    You may also be leaking tempArrayC, if tableDataSourceC has the retain attribute.


    Code:
    	NSArray *tempArrayJ = [[NSArray alloc] init];
    	self.tableDataSourceJ = tempArrayJ;
    	NSArray *sortedArrayJ = [tempArrayJ sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    	[sortedArrayJ release];
    
    The same basic pattern of mistakes:
    1. You sort an empty array.
    2. You release the sorted empty array you don't own.
    3. You may be leaking tempArrayJ.

    You need to review the memory management rules.
    http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html


    This kind of error almost always means one thing: you've released an object you don't own.

    The sequence of events behind this error are as follows.
    1. You release an object you don't own.
    2. The object is dealloc'ed, and its memory is freed.
    3. You still have a pointer to the dealloc'ed old object.
    4. Another object needs to be created.
    5. The recently freed memory is alloc'ed for the new object.
    6. At this point, the old pointer (step 3) points to a completely new object, of a completely different class.
    7. You send a message to the old object pointer, expecting it to be the old object's type.
    8. The old pointer is no longer pointing to the same object as before, not even an object of the same type, so the new object can't understand the message.
    9. A message appears that looks like:
    "-[NewObjectsClassName badMessageSelector]: unrecognized selector sent to instance incorrectlyReleasedAndRecycledObjectsAddress"

    So decoding the specific message you posted. You released an object, and it was dealloc'ed. Its memory was used to make a new object of type __NSCFDictionary. A message was sent to the old object's pointer, and that message is caseInsensitiveCompare:. The object's address is 0x5f4a7b0.


    Learn how to use zombies. Also learn why you should use them.
    http://forums.macrumors.com/showthread.php?p=11391219&highlight=#post11391219
     

Share This Page