2013-10-25 2 views
20

У меня есть массив с контентом. как обычно, он содержит 20 объектов. Я хочу, чтобы один и тот же массив разбился на 2 раздела в Tableview. Я пытаюсь реализовать его с помощью NSMake в текущем массиве. Например, мне нужно попасть в первую секцию 3 таблицы, а вторая будет содержать все остальные (17 строк).Как создать подрамник NSArray с использованием NSRange?

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; 
    } 

Может ли кто-нибудь помочь мне с этим?

+4

Параметры NSMakeRange (местоположение, длина). Возможно, вы думаете, что это что-то еще? –

+0

Если у вас жесткий диапазон, зачем беспокоиться о создании подмассива? Просто верните hardcoded count для каждого раздела и избегайте всех накладных расходов на создание 'NSRange' и потраченного впустую' NSArray'. – rmaddy

+0

@rmaddy Я более или менее задал тот же вопрос, он сказал, что хочет реальных объектов. –

ответ

53

NSMakeRange определяется как (startingIndex, length), а не (start, end), которому кажется, что вы пытаетесь его использовать.

Так что, если вам нужны первые 3 объекта, то остальное она будет выглядеть следующим образом:

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; 
} 

Edit: По вашему комментарию, вы на самом деле ищете счетчик для возврата числа строк в раздел. Поскольку вы используете фиксированное количество строк, вы можете просто вернуть фактическое число в выражении case.

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; 
} 

, Вам не нужно использовать [subarrayWithRange], ни NSMakeRange. Если вам нужно в какой-то точке ссылаться на фактический массив, вы получите объект NSIndexPath, который вы можете использовать для получения объекта из вашего массива. Вам нужно будет использовать свойства раздела и строки.

Edit: NSRange ->NSMakeRange

+0

Привет, Джоэл, Итак, как я могу делать то, что мне нужно? Я использую count, потому что мне нужно вернуть numberOfRowsInSection: – Anton

+0

@Anton см. Мой обновленный ответ. Предполагается, что вы хотите вернуть массив. –

+0

во втором сеансе он всегда принимает строки из 0. Мне не нужно возвращать количество объектов массива. раздел 1 должен содержать объекты от 1 до 3, а раздел 2 должен содержать от 4 до 20. – Anton

5

Как и другие отметили, вы используете NSRange неправильно.

определение Это является

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

поэтому второй параметр структуры является длина диапазона, а не место последнего элемента, как вы, видимо, думают.


Это, как говорится, то, что вы делаете, намного сложнее, чем должно быть.

В чем заключается цель создания подмассива известной длины и последующего возврата длины самого подмассива? Имея это в виду:

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

следует (с помощью NSRange правильно)

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

, но это может быть на самом деле просто

return 6; 

или если длина диапазона является параметром

return length; 

Опять же, нет нужно в мире срезать массив и считать. Длина известна априори.


Таким образом, в контексте UITableViewDataSource, вы должны

  • возврата счетчика для каждого раздела в -tableView:numberOfRowsInSection:. Что-то вроде

    switch(section) { 
        case 0: return 2; 
        case 1: return 18; 
    }  
    
  • возвращения фактические объекты в tableView:cellForRowAtIndexPath:. Что-то вроде

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

В качестве дополнительного наконечника, я бы посоветовал, используя различные обозначения для строительных структур

NSMakeRange(0, 42) 

можно записать

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

который намного более читаемым (и менее подверженным ошибкам, особенно когда вы находитесь в сомнение в значении параметров).

Даже

(NSRange){ 0, 42 } 

является приемлемым. Я думаю, что лучше (и короче), чем NSMakeRange, но он теряет преимущества или удобочитаемость.

1

Ok У меня есть решить мой вопрос

В моем Fetcher классе я сделал

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

затем

- (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; 
} 

затем в методе cellForRowAtIndexPath:

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

пункта - это мой NSObject с MVC

Так Он работает, как я хотел :)

Спасибо за все пытался помочь мне.

Cheers

Смежные вопросы