How do we pass NSArray as reference

Discussion in 'Mac Programming' started by anni.saini, Dec 22, 2009.

  1. anni.saini macrumors newbie

    Joined:
    Jul 15, 2009
    #1
    Hi,

    can we pass NSArray as reference, if yes then how?

    I had tried as

    NSMutableArray *temp;
    ...
    [self set:temp];
    ...
    NSLog(@"%@", temp);

    - (void) set:(NSArray*) t
    {
    t = [NSArray arrayWithObject:mad:"Test"];
    }

    getting output as null.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Every object in objective-C is a pointer, so every pass of an object is by reference. Have you tried the code in-line without the method call to see if it works?

    In any event, that method is dangerous. If there is an object being pointed to by the parameter, the reference will be lost. This will mean a memory leak unless you're using GC.

    You may also wish to print the pointer with the %p specifier a few places to see what's going on, and/or use the debugger.

    -Lee

    EDIT: Also, you define an NSMutableArray (which is an NSArray), but in your method you assign an NSArray pointer to it. If you ever try to use NSMutableArray methods on this, they will fail (as an NSArray is not an NSMutableArray).
     
  3. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #3
    You're both a little confused. Try this:

    Code:
    NSMutableArray *temp;
    ...
    [self set: [COLOR="Blue"]&[/COLOR]temp];
    ...
    NSLog(@"%@", temp);
    
    - (void) set:(NSArray[COLOR="Blue"]*[/COLOR]*) t
    {
         [COLOR="Blue"]*[/COLOR]t = [NSArray arrayWithObject:@"Test"];
    }
    
    Your problem is that you are passing the pointer value of "t" by value. Normally, this isn't a problem, but you're expecting to change the actual value of the original pointer itself, which means you need to pass the address of that pointer variable to the function, be it by reference or by pointer.

    It's been a long time since I've coded in Objective-C, so I don't know if you can pass "by reference" like you can in C++. You can definitely do a double-pointer, though, which is logically the same thing as passing a reference to a pointer.


    EDIT: lee is not wrong about the rest of the stuff he pointed out.
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    Ah, good call. Not at a mac, and didn't think that all the way through.

    -Lee
     
  5. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #5
    No actual memory leak here because the class method arrayWithObject: creates an autoreleased object. In this case, if you want to keep the object, you would need to retain it.

    What would make the most sense would be for the set method to return an array

    - (NSArray *)set {
    return [NSArray arrayWithObject:mad:"Test"];
    }

    then, above,


    temp = [self set];
     
  6. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #6
    Agreed, but then he wouldn't have learned why his original code didn't work. :cool:
     
  7. anni.saini thread starter macrumors newbie

    Joined:
    Jul 15, 2009
    #7
    Thanx for your valuable reply...

    could you please tell me why the solution suggested by "Detrius", not for mac. If so, so can i achieved it by any other way...

    and i don't want to change method signature means it should take one argument and return void.

    - (void) set:(<NSArray>) t;
     
  8. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #8
    Other than the fact that the language is Objective-C, there's nothing about it that's Mac-specific. You can do double-pointers in C and C++.
     
  9. sammich macrumors 601

    sammich

    Joined:
    Sep 26, 2006
    Location:
    Sarcasmville.
    #9
    He said that he was not in front of his mac so he can't test out his theory.
     
  10. anni.saini thread starter macrumors newbie

    Joined:
    Jul 15, 2009
  11. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #11
    Just for future reference, I think it's a really bad idea to name an Objective-C mehod simply "set". The Cocoa runtime uses setXXX for Bindings and KVC. You could call it setArray or better yet something more descriptive like setOrders or setEmployees.
     
  12. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #12
    Indeed. One of the difficult things to get used to in Objective C/Cocoa is that method names are visible outside the bounds of the source code. When subclassing, one should take care not to accidentally override a superclass method by using an obvious name.
     
  13. anni.saini thread starter macrumors newbie

    Joined:
    Jul 15, 2009
    #13
    I got it, please correct me if I'm wrong...

    NSMutableArray *temp = [[NSMutableArray alloc] init];

    ...
    [self setArray:temp];
    ...
    NSLog(@"%@", temp);

    - (void) setArray:(NSMutableArray*) t
    {
    [t addObjectsFromArray:[NSArray arrayWithObjects:mad:"Test", @"test1", nil]];
    }
     
  14. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #14
    Not quite. What you probably want is an instance variable, declared in your interface (.h) file, that will keep track of the array. Let's say that variable is called myArray.

    Code:
    @interface MyObject : NSObject {
        NSArray	*myArray;
    }
    
    - (void)setArray:(NSArray*)newArray;
    
    @end
    So now, back in your implementation (.m) file, you can pass any array to the setter method, from anywhere, and it will assign it to the myArray variable. In general, you don't want to modify the object passed into the setter method, just assign it. For example:

    Code:
    NSMutableArray *temp = [NSArray array];
    // Add objects to array here, objects added are each retained by the array object
    [self setArray:temp];
    
    - (void)setArray:(NSArray*)newArray {
    	[newArray retain];
    	[myArray release];
    	myArray = newArray;
    }
    That's if your instance variable is a mutable array. If you want your instance variable to be immutable, but still want to pass mutable arrays into your setter, you'll have to copy the array using something like arrayWithArray:

    Also, you should wrap your code blocks in code tags when posting so it's readable.
     
  15. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #15
    NSMutableArray already has a -setArray: method. What I think you a trying to do would look like this
    Code:
    temp = [NSMutableArray new];
    
    [temp setArray:[NSArray arrayWithObjects:@"Test", @"test1", nil]];
    
    -setArray: replaces the contents of a NSMutableArray with the contents of another array, removing any existing contents. -addObjectsFromArray: does not remove the existing content.

    You need to think in terms of messages. -setArray: is a message that you send to the NSMutableArray. This English syntax, in the form of subject command.
     

Share This Page