¿Cómo utilizo un método para cambiar un puntero?

I'm working on an iPhone app using objective C. I've got class A, which creates an NSMutableArray pointer called "list". But, in class A, I never create an object for it to point to. Instead, I call a class method in class B, to get some data from an sqlite database, and populate an NSMutableArray object there. I want to be able to set the pointer in class A to point to the NSMutableArray object created in the class B method by passing it as an argument to the method. I can't do it by returning the array because I want to return the sqlite result.

I wonder if I'm doing this right? I haven't written the entire method yet (when it's done it'll be pretty long), but I want to know if I'm doing the pointer stuff correctly before I get started on the rest.

//ClassA.m

//...
NSMutableArray *list;
[ClassB populateArrayFromSqlite:&list];
//Now do stuff with "list", which should point to the array created in populateArrayFromSqlite
//...

//ClassB.m
+(int)populateArrayFromSqlite:(NSMutableArray**)ar {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    //Here there will be code that populates the array using sqlite (once I write it)
    //And then I need to set the "list" pointer in ClassA.m to point to this array
    ar = &array; //Is this how?

    return resultFromSqlite;
}

Did I do it right? Or am I not understanding something? I guess this pointer-to-pointer stuff just doesn't click with me yet. After reading a few general sources about pointers, I suspect this is how I'd do it but part of me doesn't understand why the ar argument can't just be a regular pointer (as opposed to a pointer-to-pointer).

preguntado el 08 de enero de 11 a las 19:01

2 Respuestas

Pointers to pointers are a bit escheric, yes. The simple way to do it would be to create an empty array in A and pass a regular array pointer to B that would just fill it. If you insisted on creating the array in B, I think you could do this:

- (void) createArray: (NSMutableArray**) newArray
{
    NSAssert(newArray, @"I need a pointer, sweetheart.");
    *newArray = [[NSMutableArray alloc] init];
    [*newArray addObject:...];
}

Respondido el 08 de enero de 11 a las 23:01

+1 though it'd be best to check if (newArray != nil), just so you don't accidentally dereference a null pointer. :) - Dave DeLong

Right. I mentioned this possibility just to answer the pointer-to-pointer question, in practice I’d certainly use the simpler solution I mentioned first. I’ll add an assert to make things clear. - zoul

Thanks, I didn't even think of creating the object first in class A and passing a pointer to it to the class B method. Also, with your example I think I understand this. Passing the address of a pointer in the newArray argument actually sends a copy of a pointer to the pointer, and by dereferencing it, you get the pointer itself, which you can then assign a new address to, correct? - Adán

Yes, that’s how I understand it, too. - zoul

Goodness. Don't do that! Reaching into another class in such a fashion to set an ivar is an egregious abuse of encapsulation and should nunca be done in a properly written/architected Objective-C application! - bbum

Changing pointers to objects like this is fairly uncommon in Objective-C. The main time we see stuff like this is when a method has a potential for failure, at which point we'll pass in a pointer to an NSError reference. For example, NSFileManager's - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error.

The far more common way to do this would be to have the method return the array:

NSMutableArray * list = [ClassB mutableArrayFromSQLite];

Respondido el 08 de enero de 11 a las 23:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.