What is the difference between these two methods?

Discussion in 'Mac Programming' started by teek, Mar 5, 2010.

  1. teek macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #1
    What is the difference between these two ways of creating an NSArray.

    Besides one being a class method and the other being an instance method. What is the difference ? When I use the class method my application will crash when I try to access the elements of my array.

    +(id)arrayWithObjects:(id)firstObj, ...;

    -(id)initWithObjects:(id)firstObj, ...;

    myData = [NSArray alloc] initWithObjects:mad:"foo",@"bar",nil];

    do something with myData[index] all OK.

    myData = [NSArray arrayWithObjects:mad:"foo",@"bar",nil];

    do something with myData[index] will crash without any exception or stacktrace.


    What am I missing ?
     
  2. whooleytoo macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #2
    +(id)arrayWithObjects: (id)firstObj, ...

    This will return an NSArray, which will be valid in the current scope. If you need this later, you need to retain the array (and release it when you're done).

    -(id)initWithObjects: (id)firstObj, ...

    This returns an NSArray with a retain count of 1. You don't need to retain it, but you do need to release it when done.

    They're also used slightly differently, init.. methods are normally used in conjunction with alloc.

    Code:
    NSArray* myArray = [NSArray arrayWithObjects: ......];
    [myArray retain];
    .
    .
    [myArray release];
    
    OR
    
    NSArray* myArray = [[NSArray alloc] initWithObjects: .....];
    .
    .
    [myArray release];
    Edit - I should add, the retain/release lines may not be necessary if you're using garbage collection; but I think it's useful to know all the same.
     
  3. teek thread starter macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #3
    Ok I see. But how do I know when I have to retain the object ? I don't get it.
     
  4. whooleytoo macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #4
    If you create an object with a class method such as arrayWith... , it's only guaranteed to be valid for the current scope (i.e. in the function/method you call arrayWith...). If you (say) assign that array to an instance variable, and want to use it later, you need to retain it.

    E.g.

    Code:
    - (void) setupArray
    {
        _theArray = [NSArray arrayWithObjects:....];
    
        // _theArray is valid here
    }
    
    - (void) useArray
    {
        id first = [_theArray objectAtIndex:0];
        // _theArray may not be valid here, this will probably crash!
    }
    .
    .
    [self setupArray];
    [self useArray] 
    
    If you wanted the above example to work correctly, you'd need to add a [_theArray retain] as the second line in setupArray.

    As a general rule:
    - if you use alloc..init, or if you use copy.. methods, then you need to release the objects they return once you're finished with them.

    - For objects returned from other methods (such as arrayWithObjects:...) you need to retain them if you need to use them in another scope.

    - Every object you retain, you need to release later

    So, you can use the two methods you mentioned for the same tasks, but generally you'd use arrayWithObjects if you want to create an array just for the current function/method; whereas you'd normally use alloc & initWithObjects: if you're creating a "permanent" array which you'll be using often/later.
     
  5. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #5
  6. whooleytoo macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #6
  7. teek thread starter macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #7
    Ah this is good info, thank you very much whooleytoo!
    And thank you too gnasher729, reading it now :)
     

Share This Page