¿Cómo crear un subarray de NSArray usando NSRange?

Tengo una matriz con contenido. como siempre contiene 20 objects. Quiero que la misma matriz se divide en 2 secciones en Tableview. Estoy intentando implementarlo con NSMake en la matriz actual. Por ejemplo, necesito get en la primera sección de tabla 3 filas y la segunda contendrá todo el rest (17 filas).

switch (section) { case 0: return [[array subarrayWithRange:NSMakeRange(3, 8)] count]; // in this line, it always takes from the first object in array, despite I told hime start from 3 (If I understand right, how to works NSMakeRange) break; case 1: return [[array subarrayWithRange:NSMakeRange(9, 19)] count]; // here my app is crashing with an error //*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray subarrayWithRange:]: range {9, 19} extends beyond bounds [0 .. 19]' default: break; } 

¿Alguien me puede ayudar con eso?

NSMakeRange se define como (startingIndex, length) , no (start, end) que parece NSMakeRange cómo está intentando usarlo.

Entonces, si necesita los primeros 3 objects, el rest se vería así:

 switch (section) { case 0: // This returns objects 0-2 in the array return [array subarrayWithRange:NSMakeRange(0, 3)]; case 1: // This returns objects 3-20 in the array return [array subarrayWithRange:NSMakeRange(3, 17)]; default: break; } 

Editar: según su comentario, en realidad está buscando el recuento para regresar en número de filas en la sección. Dado que está utilizando un número fijo de filas, puede devolver el número real dentro de la instrucción de caso.

 switch (section) { case 0: // This returns the count for objects 0-2 in the array return 3; case 1: // This returns the count for objects 3-20 in the array return 17; default: break; } 

En realidad no necesita usar [subarrayWithRange] ni NSMakeRange . Si necesita referencer en algún momento la matriz real, obtendrá un object NSIndexPath que puede usar para get el object de su matriz. Deberá usar las properties de sección y fila.

Editar: NSRange -> NSMakeRange

Como otros han observado, está utilizando NSRange incorrectamente.

Su definición es

 typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange; 

así que el segundo parámetro de la estructura es la longitud del range, no la location del último elemento como aparentemente piensas.


Dicho eso, lo que estás haciendo es mucho más complicado de lo que debería ser.

¿Cuál es el propósito de producir un subarray de una longitud conocida y luego devolver la longitud del subarray mismo? Teniendo esto en count:

 return [[array subarrayWithRange:NSMakeRange(3, 8)] count]; 

debe ser (usando NSRange correctamente)

 return [[array subarrayWithRange:NSMakeRange(3, 6)] count]; 

pero en realidad puede ser simplemente

 return 6; 

o si la longitud del range es un parámetro

 return length; 

Una vez más, no hay necesidad en el mundo de cortar una matriz y contar. La longitud se conoce a priori.


Entonces, en el context de UITableViewDataSource , tienes que

  • devuelva el recuento para cada sección en -tableView:numberOfRowsInSection: Algo como

     switch(section) { case 0: return 2; case 1: return 18; } 
  • devuelve los objects reales en tableView:cellForRowAtIndexPath: Algo como

     id object = nil; switch (indexPath.section) { case 0: object = self.objects[indexPath.row]; break; case 1: object = self.objects[2 + indexPath.row]; break; } ... 

Como consejo adicional, aconsejaría usar una notación diferente para build estructuras

 NSMakeRange(0, 42) 

puede escribirse

 (NSRange){ .location = 0, .length = 42 } 

que es mucho más legible (y less propenso a errores, especialmente cuando tiene dudas sobre el significado de los parameters).

Incluso

 (NSRange){ 0, 42 } 

es aceptable. Creo que es mejor (y más corto) que NSMakeRange , pero pierde los beneficios o la legibilidad.

Ok, tengo que resolver mi problema

En mi class de búsqueda, hice

 _sectionOne = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)]]; _sectionTwo = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 17)]]; 

entonces

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { switch (section) { case 0: return [_sectionOne count]; break; case 1: return [_sectionTwo count]; break; default: break; } return 0; } 

luego en el método cellForRowAtIndexPath:

  switch (indexPath.section) { case 0: item = [_sectionOne objectAtIndex:indexPath.row]; break; case 1: item = [_sectionTwo objectAtIndex:indexPath.row]; break; default: break; } 

artículo: es mi NSObject con MVC

Así que está funcionando como quería 🙂

Gracias por todos tratando de ayudarme.

Aclamaciones