Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ATG

macrumors regular
Original poster
Aug 7, 2005
187
0
Sorry for asking so many simple questions. i would like to create more than one array. When I create my first array I do this:
Code:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
Now I have a problem, I want to create a second array but don't know how to do it. Creating an array in the same way as before just crashes my app (which is what I expected it to do).

Please Help. :confused: :eek:
 

Omen88

macrumors regular
Jan 8, 2002
177
0
Flanders (Belgium)
ATG said:
Sorry for asking so many simple questions. i would like to create more than one array. When I create my first array I do this:
Code:
NSArray *myArray = [[NSArray alloc] init];
Now I have a problem, I want to create a second array but don't know how to do it. Creating an array in the same way as before just crashes my app (which is what I expected it to do).

Please Help. :confused: :eek:

This answer could be terribly stupid, but did you give the second array a different name? Like:
Code:
NSArray *myOtherArray = [[NSArray alloc] init];

and don't forget to release it, when you're done with it.
Code:
[myArray release];
 

ozubahn

macrumors regular
Feb 15, 2003
100
0
Connecticut
ATG said:
Code:
NSArray *myArray = [[NSArray alloc] init];

To make a second array, you can use the same alloc/init call and assign the result to a second (different) NSArray* variable or to a different slot in a container object. That should not crash your app, so you might have other problems elsewhere. Even if you assign both new arrays to the same variable, I would not expect a crash, just memory leaks. That said, creating an NSArray in this way is sort of odd. NSArray is a non-mutable type; you can't add any objects to it after it is created. What the line above does is create an empty container that can only remain empty for its entire existence. You either want an NSMutableArray if adding and removing objects is needed, or you should use one of the NSArray factory methods that creates a pre-filled nonmutable array.
 

ATG

macrumors regular
Original poster
Aug 7, 2005
187
0
Oops. I forgot to say that yes they are mutable arrays. So I'm doing this:
Code:
NSMutableArray * myArray = [[NSMutableArray alloc] init];
I am releasing them. The only thing I can think of is my release statements. At the moment I have this:
Code:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray * facArray = [[NSMutableArray alloc] init];
//code that uses facArray
[facArray Release]

NSMutableArray * pfacArray = [[NSMutableArray alloc] init];
//code that uses pfacArray
[pfacArray Release]

If that code is right I'll have a look for any mistakes in the 'body'.
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
Have you tried running it in the debugger? When you do you should be able to tell more accurately where it crashes.
 

ATG

macrumors regular
Original poster
Aug 7, 2005
187
0
All my releases have lower-case 'r's
I'm going to run it in the debugger right now.

AHA: If I take the init of my second array so it looks like this...
Code:
NSMutableArray *pfacArray [NSMutableArray alloc]
...it won't crash. This I think means that my problem is with the 'init'. Any ideas? :confused:
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
The correct init call for mutable array is initWithCapacity: not just init ... as in:
Code:
NSMutableArray * pfacArray = [[NSMutableArray alloc] initWithCapacity:100];
Look in the reference documentation for class XXX under the headline Creating an XXX to find proper ways of instantiating objects of that class. As you can see, an alternative to initWithCapacity would be:
Code:
NSMutableArray *pfacArray = [NSMutableArray arrayWithCapacity:100];
In this last case, as with other methods that return an object, the factory class methods with a '+' return objects that must not be released, since they already have an autorelease pending.
 

ATG

macrumors regular
Original poster
Aug 7, 2005
187
0
Nope. It still crashes. I've tried both of your's, not that I understand your last statement about autoreleasing and class methods. Any other ideas? :confused:
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
I assume you changed it for both arrays? Can you post the entire method code? Or I can PM my e-mail address to you so that you can mail the entire project to me if you want.
 

admanimal

macrumors 68040
Apr 22, 2005
3,531
2
As someone else pointed out, you do not need to release either of those arrays, because init methods autorelease them, and you have not explicitly retained them. Releasing a variable that has not been retained can cause a crash.

You can PM me the code if you'd like as well.
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
ATG said:
Nope. It still crashes. I've tried both of your's, not that I understand your last statement about autoreleasing and class methods. Any other ideas? :confused:

While this may not be the cause of the crash, it is very important to understand the point he was making.

The difference between the two lines he gave was:

Code:
NSMutableArray * pfacArray = [[NSMutableArray alloc] initWithCapacity:100];

In this case, because you're calling the alloc method to allocate memory for the pfacArray, it's your responsibility to call its release method later to free it - otherwise it'll leak.

Code:
NSMutableArray *pfacArray = [NSMutableArray arrayWithCapacity:100];

In this case, you're not calling alloc (or copy), so it's not your responsibility to call the release method - if you do so, your app may well crash.

That's because the arrayWithCapacity method is autoreleasing the array it returns to you (i.e. instead of the last line in arrayWithCapacity: being something like "return newArray;" it's probably "return [newArray autorelease];").

However, if you want to hold on to the pfacArray returned (say, if you need to use it in later methods), you'll need to call it's retain method to ensure it doesn't get freed while you still need it, then call release once you're done with it.

Code:
// Create a new array via alloc..init
- (void) createNewArray1
{
    NSMutableArray* myArray = [[NSMutableArray alloc] initWithCapacity:10] ;
    
   // Do stuff with myArray

   [myArray release] ;
}

/* Now, what if you want to return that array from that function? You can't release the array before you return it (or you'll be returning nothing!), so how do you make sure it doesn't get leaked? Use autorelease */

- (NSMutableArray*) createNewArray2
    NSMutableArray* myArray = [[NSMutableArray alloc] initWithCapacity:10] ;
    
   // Do stuff with myArray

   return [myArray autorelease] ;
}

/* Or, you could just: */
- (NSMutableArray*) createNewArray3
    NSMutableArray* myArray = [NSMutableArray arrayWithCapacity:10] ;
    
   // Do stuff with myArray

   return myArray;
}

/* Note, in createNewArray3, you didn't release or autorelease the array. That's because, you didn't create it (via alloc or copy), so you're not responsible for releasing it. */
Hope I've helped and not confused! ;)
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
admanimal said:
As someone else pointed out, you do not need to release either of those arrays, because init methods autorelease them, and you have not explicitly retained them. Releasing a variable that has not been retained can cause a crash.

I'm afraid that's not the case, init methods never autorelease the object they return; and thus should always be 'balanced' with a release.
 

caveman_uk

Guest
Feb 17, 2003
2,390
1
Hitchin, Herts, UK
gekko513 said:
The correct init call for mutable array is initWithCapacity: not just init ... as in:
Code:
NSMutableArray * pfacArray = [[NSMutableArray alloc] initWithCapacity:100];
What's wrong with just plain 'init'? It works just fine as it's inherited from NSObject. initWithCapacity is probably faster to add objects to later as there's more preallocated space for the array but both work fine. It's not really helping the guy find his crasher.
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
caveman_uk said:
What's wrong with just plain 'init'? It works just fine as it's inherited from NSObject. initWithCapacity is probably faster to add objects to later as there's more preallocated space for the array but both work fine. It's not really helping the guy find his crasher.

That's right, it's just less efficient, that's all.

ATG, feel free to post more of the code here so we can look at it.
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
whooleytoo said:
That's right, it's just less efficient, that's all.

ATG, feel free to post more of the code here so we can look at it.
OK, I might have gotten that wrong then. I only initialize objects with the methods that are explicitly mentioned in the reference document for that class. My motivation for that comes from Java where some classes only have constructors that require arguments. I wasn't confident that a simple init would always be enough. I know for sure that my own classes are usually not initialized properly unless they are called with my own initializers, but I guess that is my fault :eek:
 

gekko513

macrumors 603
Oct 16, 2003
6,301
1
Oh, and I have sent a PM with some help for the original poster. When I plugged the method code into a project of my own I found that it went into an infinite loop and did not really crash on the alloc init statements. So hopefully that has solved the problem.
 

caveman_uk

Guest
Feb 17, 2003
2,390
1
Hitchin, Herts, UK
gekko513 said:
OK, I might have gotten that wrong then. I only initialize objects with the methods that are explicitly mentioned in the reference document for that class. My motivation for that comes from Java where some classes only have constructors that require arguments. I wasn't confident that a simple init would always be enough. I know for sure that my own classes are usually not initialized properly unless they are called with my own initializers, but I guess that is my fault :eek:
Generally in objective-C/Cocoa you override the 'init' method if you have anything special to do for your class having first called [super init] which generally will be the one in NSObject. I don't know about 'initWithCapacity' specifically but most of the 'initWith..' methods probably also call [super init] somewhere along the line.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.