2013-03-01 3 views
0

Я передаю ivar (NSMutableArray) в какой-то метод. Я ожидал, что если я изменю объект внутри функции, он будет отражен вне функции, но в этом случае мне нужно установить объект; что-то вроде следующего:Как передать ivar в функцию и установить ее, не теряя ссылку на исходный объект

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

Но я заметил, что ссылка на память о imAnIvar внутри функции меняет, когда я установил его, и учитывая, что фактическое Ивар не меняется. Я понимаю, что проблема в том, что я изменяю ссылку на объект внутри метода, поэтому он перестает указывать на ivar, а затем указывает на другое направление случайной памяти.

Я думал об одно решение этой проблемы, и это может быть, чтобы гарантировать, что Ивар не ноль перед вызовом функции и сделать что-то вроде этого:

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

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

Так я использую исходный объект вместо устанавливая его напрямую. Проблема в том, что для того, чтобы это работало, мне нужно убедиться, что ивар не ноль, который, я думаю, не чист, потому что мне нужно будет сделать что-то подобное при каждом вызове метода:

if(!_ivar){ 
    //alloc it 
} 

Итак, мой вопрос: есть ли способ заставить локальную переменную области указывать на исходную переменную, даже если я ее настраиваю? если нет, есть ли более чистый способ сделать эту работу?

+0

«Я заметил, что обращение к памяти о imAnIvar внутри функции изменяется, когда я установите его "- WAT? –

+0

Извините, я изменю его, чтобы сделать его более понятным. – clopez

+0

, если вы допустили явную ошибку, затем посмотрите мой ответ и обратите внимание, что в C аргументы функции передаются по значению, а не по ссылке. –

ответ

3

Вы имеете в виду это?

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

// call it as: 

SomeClass *foo = someObject; 
NSLog(@"Before: %@", foo); 
[self setFoo:&foo]; 
NSLog(@"After: %@", foo); 
+0

Я так думаю, позвольте мне попробовать! Спасибо – clopez

+2

+1, но это странный/необычный способ делать что-то (за редким исключением). Обычный способ справиться с этим состоит в том, чтобы иметь '-someMethod: ...' * return * массив, тогда вызывающий делает все, что нужно сделать с возвращаемыми значениями (например, добавляя их к своему внутреннему массиву ivar). Если '-someMethod: ...' находится в том же классе, что 'imAnIvar' является переменной экземпляра,' someMethod: ...' должен напрямую манипулировать ivar (/ property), не принимая его в качестве аргумента. –

+0

@AndrewMadsen Спасибо. Яп. Я чувствую, что это (другая) проблема XY, не так ли? –

-2

Я считаю, что вы можете использовать - (id)copy; функцию NSObject

так что ваш код может выглядеть следующим образом:

- (void)someFunction:(NSString *)someArg 
{ 
    NSString *str = [someArg copy]; 
} 
+0

Проблема в том, что некоторые объекты вообще не копируются (NSObject), а некоторые не делают глубоких копий. – CodaFi

+2

@CodaFi Проблема в том, что автор этого ответа читал только заголовок, а не вопрос. –

1

Почему бы не использовать поглотитель для массива, так что вам не нужно проверить для того, чтобы массив был равен нулю при его использовании?

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

И когда вы должны установить значение в массив, как вы упомянули в вашем вопросе, вы можете использовать

[self.iAmAnIvar removeAllObjects]; 
[self.iAmAnIvar addObject:someObj];