una retornar recibe que pasar parametro multiplicacion matriz matrices llenar funciones funcion con como bidimensional arreglo objective-c

objective-c - retornar - pasar un arreglo como parametro en java



¿Es posible enviar una matriz en Obj-c para una función de argumentos variables? (8)

Desafortunadamente (Objective-) C no proporciona una manera de hacerlo. El método executeUpdate necesitaría aceptar un NSArray en lugar de una lista de argumentos variables en este caso.

Sin embargo, si conoce la cantidad de entradas en la matriz (de todos modos, tiene la cantidad en la cadena en el ejemplo), puede, por supuesto, hacer algo como

[db executeUpdate:@"insert into test (a, b) values (?, ?)", [values objectAtIndex:0], [values objectAtIndex:1]]

Si executeUpdate es un método de biblioteca externo y esa biblioteca no ofrece una versión del método que acepte un NSArray, podría crear su propia función de contenedor. La función tomaría la cadena de consulta y una matriz como argumento. Esta función llamaría entonces al método executeUpdate con la cantidad correcta de argumentos en función de la longitud de la matriz, algo similar a

if ([values count] == 1) { [db executeUpdate:query, [values objectAtIndex:0]]; } else if ([values count] == 2) { [db executeUpdate:query, [values objectAtIndex:0], [values objectAtIndex:1]]; }

a continuación, podría llamar a esta nueva función como

executeUpdateWrapper(@"insert into test (a, b) values (?, ?)", values);

El inconveniente obvio en esta solución es que necesita manejar todas las longitudes posibles de la matriz por separado en la función y tiene una gran cantidad de código de copiar y pegar.

En Python es fácil construir un diccionario o matriz y pasarlo desempaquetado a una función con parámetros variables

Tengo esto:

- (BOOL) executeUpdate:(NSString*)sql, ... {

Y la forma manual es esta:

[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" , @"hi''", // look! I put in a '', and I''m not escaping it! [NSString stringWithFormat:@"number %d", i], [NSNumber numberWithInt:i], [NSDate date], [NSNumber numberWithFloat:2.2f]];

Pero no puedo codificar los parámetros que estoy llamando, quiero:

NSMutableArray *values = [NSMutableArray array]; for (NSString *fieldName in props) { .. .. [values addObject : value] } [db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,??values];


Para lograr lo que desea, debe usar "varargs", como lo usa su método, o puede pasar una matriz de valores, algo así como [db executeUpdate:sql withValues:vals]; , y luego extraiga los valores en el método. Pero no hay forma de hacer algo más "Pythonic", como desempaquetar automáticamente una tupla de valores, á la def executeUpdate(sql, *args) .


Yo quería hacer lo mismo. Se me ocurrió lo siguiente, que funciona bien, dadas algunas limitaciones en las variables de entrada.

NSArray* VarArgs(va_list ap) { id obj; NSMutableArray* array = [NSMutableArray array]; while ((obj = va_arg(ap, id))) { [array addObject:obj]; } return array; } #define VarArgs2(_last_) ({ / va_list ap; / va_start(ap, _last_); / NSArray* __args = VarArgs(ap); / va_end(ap); / if (([__args count] == 1) && ([[__args objectAtIndex:0] isKindOfClass:[NSArray class]])) { / __args = [__args objectAtIndex:0]; / } / __args; })

Usando lo anterior, puedo llamar a lo siguiente con un NSArray o con varargs.

// ''...'' must be objc objects with nil sentinel OR an NSArray with nil sentinel - (void)someMethod:(NSString *)sql, ... { NSArray *args = VarArgs2(sql); // Do stuff with args }

Un consejo más es usar lo siguiente en el prototipo para que el compilador verifique que no haya nada malo para evitar posibles problemas. Lo saqué de los encabezados de las manzanas ...

- (void)someMethod:(NSString *)sql, ... NS_REQUIRES_NIL_TERMINATION;


Hay un buen ejemplo de cómo puede ir de NSArray a va_list aquí (vea "va_list in Cocoa" y "Creating a fake va_list" hacia la parte inferior):

http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

Aquí hay un adelanto ("argumentos" es NSArray):

char *argList = (char *)malloc(sizeof(NSString *) * [arguments count]); [arguments getObjects:(id *)argList]; contents = [[NSString alloc] initWithFormat:formatString arguments:argList]; free(argList);

No del todo python o ruby, pero bueno ...


Deberías usar la nueva versión de FMDB http://github.com/ccgus/fmdb . Tiene el método que necesitas:

- (BOOL) executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;


adicionalmente a la solución de robottobor: si agrega la siguiente macro:

#define splitAlternatingArray(args,arg1,arg2) / NSMutableArray *arg1 = [NSMutableArray array];/ NSMutableArray *arg2 = [NSMutableArray array];/ {/ BOOL isFirst = YES;/ for (id arg in args) {/ if (isFirst) {/ [arg1 addObject:arg];/ } else {/ [arg2 addObject:arg];/ }/ isFirst = !isFirst;/ }/ }

entonces puedes hacer cosas complicadas como:

- (id)initWithObjectsAndKeys:(id)firstObject, ...{ NSArray *objKeyArray = VarArgs2(firstObject); splitAlternatingArray(objKeyArray,objs,keys); return [self initWithObjects:objs forKeys:keys]; }


Chuck tiene razón, no hay un argumento apropiado para desempaquetar en Objective-C. Sin embargo, para los métodos que requieren terminación nil (NS_REQUIRES_NIL_TERMINATION), puede expandir la lista de variables más grande que lo que se necesita al usar un acceso de matriz que devuelve nil cuando index >= count . Esto es ciertamente un truco, pero funciona.

// Return nil when __INDEX__ is beyond the bounds of the array #define NSArrayObjectMaybeNil(__ARRAY__, __INDEX__) ((__INDEX__ >= [__ARRAY__ count]) ? nil : [__ARRAY__ objectAtIndex:__INDEX__]) // Manually expand an array into an argument list #define NSArrayToVariableArgumentsList(__ARRAYNAME__)/ NSArrayObjectMaybeNil(__ARRAYNAME__, 0),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 1),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 2),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 3),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 4),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 5),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 6),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 7),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 8),/ NSArrayObjectMaybeNil(__ARRAYNAME__, 9),/ nil

Ahora puede usar NSArrayToVariableArgumentsList donde quiera que espere una lista de argumentos variables terminados en nulo (siempre que su matriz sea menor que 10 elementos). Por ejemplo:

NSArray *otherButtonTitles = @[@"button1", @"button2", @"button3"]; UIActionSheet *actionSheet = [[self alloc] initWithTitle:@"Title" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)];


Lamentablemente no. Objective-C no tiene desempaquetado de argumentos como se obtiene en muchos idiomas modernos. Ni siquiera hay una buena manera de solucionarlo que he encontrado.

Parte del problema es que Objective-C es esencialmente solo C. Hace varios argumentos que pasan con C varargs, y no hay una manera simple de hacer esto con varargs. Una discusión SO relevante .