0

I am passing an ivar (NSMutableArray) into some method. I was expecting that if I modify the object inside the function, it would be reflected outside the function, but in this case I need to set the object; something like the following:

- (void) someMethod:(SMResponseObject *)response onData:(NSMutableArray *)imAnIvar {
    imAnIvar = [response objects];
    //Some other stuff
}

But I noticed that the memory reference of imAnIvar inside the function changes when I set it, and given that, the actual ivar doesn't change. I understand that the problem is that I'm changing the reference of the object inside the method, so it stops pointing to the ivar and then it points to some other random memory direction.

I thought about one solution to this problem, and it can be to ensure that the ivar is not nil before calling the function and do something like this:

- (void) someMethod:(SMResponseObject *)response onData:(NSMutableArray *)imAnIvar {

    NSMutableArray *data = [response objects];
    [arrayForTableView removeAllObjects];
    for(id element in data){
        [imAnIvar addObject:element];
    }
    //Some other stuff
}

So I use the original object instead of setting it directly. The problem is that in order for this to work I need to ensure that the ivar is not nil, which I think is not clean, because I'll need to do something like this on every call to the method:

if(!_ivar){
  //alloc it
}

So my question is: Is there a way to force the local scope variable to point to the original variable even if I'm setting it? if not, is there any cleaner way to make this work?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
clopez
  • 4,372
  • 3
  • 28
  • 42
  • "I noticed that the memory reference of imAnIvar inside the function changes when I set it" - WAT? –  Mar 01 '13 at 16:33
  • Sorry, I will change it to make it more clear. – clopez Mar 01 '13 at 16:35
  • if you made the obvious mistake, then see my answer and note that in C, function arguments are passed by value, not by reference. –  Mar 01 '13 at 16:35

3 Answers3

3

Do you mean this?

- (void)setFoo:(SomeClass **)objPtr
{
    *objPtr = someOtherObject;
}

// call it as:

SomeClass *foo = someObject;
NSLog(@"Before: %@", foo);
[self setFoo:&foo];
NSLog(@"After: %@", foo);
  • I think so, let me try it! Thanks – clopez Mar 01 '13 at 16:35
  • 2
    +1, but it's a weird/uncommon way to do things (with some rare exceptions). The normal way to handle this is to have the `-someMethod:...` *return* an array, then the caller does whatever needs to be done with the returned values (e.g. adding them to its internal ivar array). If `-someMethod:...` is in the same class that `imAnIvar` is an instance variable of, `someMethod:...` should manipulate the ivar(/property) directly without needing to take it as an argument. – Andrew Madsen Mar 01 '13 at 16:51
  • @AndrewMadsen Thank you. Yap. I feel this is (another) XY problem, isn't it? –  Mar 01 '13 at 16:51
  • The ivar in this case is not on the same class as someMethod. That's why I'm passing it as an argument. Actually, the solution proposed by @AndrewMadsen of returning the value is the best for my case, and I think he proposed this thanks to my XY problem extra context. – clopez Mar 01 '13 at 17:25
1

Why not use a getter for the array so that you need not check for the array being nil while using it?

-(NSMutableArray *)iAmAnIvar {
   if(_iAmAnIvar == nil) {
     _iAmAnIvar = [NSMutableArray array];
   }
   return _iAmAnIvar;
 }

And when you have to set a value to the array, as you mentioned in your question, you could use

[self.iAmAnIvar removeAllObjects];
[self.iAmAnIvar addObject:someObj];
Shashank
  • 1,743
  • 1
  • 14
  • 20
-2

I believe you can use the - (id)copy; function of NSObject

so your code might look like this:

 - (void)someFunction:(NSString *)someArg
 {
     NSString *str = [someArg copy];
 }
Jules
  • 14,200
  • 13
  • 56
  • 101
Don
  • 43
  • 2
  • The problem with this is that some objects don't copy at all (NSObject), and some don't do deep copies. – CodaFi Mar 01 '13 at 16:38
  • 2
    @CodaFi The problem with this is that the author of this answer only read the title, not the question. –  Mar 01 '13 at 16:43