ios 如何使用 NSRange 创建 NSArray 的子数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19597034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:35:33  来源:igfitidea点击:

How to create a subarray of NSArray using NSRange?

iosobjective-cnsarraynsrangearrays

提问by Anton

I have an Array with content. as usual it contain 20 objects. I want the same array split into 2 sections in Tableview. I am trying to implement it with NSMake in current array. For example I need get in first tableview section 3 rows and second will contain all the rest (17 rows ).

我有一个包含内容的数组。像往常一样,它包含 20 个对象。我想在 Tableview 中将相同的数组分成 2 个部分。我正在尝试在当前数组中使用 NSMake 实现它。例如,我需要进入第一个 tableview 部分 3 行,第二个将包含所有其余部分(17 行)。

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

Does anyone can help me with that?

有没有人可以帮我解决这个问题?

回答by Joel Fischer

NSMakeRangeis defined as (startingIndex, length), not (start, end)which it seems like how you are trying to use it.

NSMakeRange被定义为(startingIndex, length),而不是(start, end)您尝试使用它的方式。

So if you need the first 3 objects, then the rest it would look like this:

因此,如果您需要前 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: According to your comment, you are actually looking for the count to return in number of rows in section. Since you are using a fixed number of rows, you can just return the actual number within the case statement.

编辑:根据您的评论,您实际上是在寻找以部分行数返回的计数。由于您使用的是固定数量的行,因此您可以在 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;
}

You do not actually need to use [subarrayWithRange], nor NSMakeRange. If you do need to at some point reference the actual array, you will get an NSIndexPath object which you can use to get the object from your array. You will need to use the section and row properties.

您实际上不需要使用[subarrayWithRange], 也不需要NSMakeRange。如果您确实需要在某个时候引用实际数组,您将获得一个 NSIndexPath 对象,您可以使用该对象从您的数组中获取该对象。您将需要使用 section 和 row 属性。

Edit: NSRange-> NSMakeRange

编辑:NSRange->NSMakeRange

回答by Gabriele Petronella

As others have noted you are using NSRangeimproperly.

正如其他人所指出的,您使用NSRange不当。

It's definition is

它的定义是

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

so the second parameter of the struct is the length of the range, not the location of last element as you apparently think.

所以结构的第二个参数是范围的长度,而不是你显然认为的最后一个元素的位置。



That being said, what you are doing it's much more complicated than it should be.

话虽如此,你正在做的事情比它应该的要复杂得多。

What's the purpose of producing a subarray of a known length and then returning the length of the subarray itself? With this in mind:

生成已知长度的子数组然后返回子数组本身的长度的目的是什么?考虑到这一点:

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

should be (using NSRangeproperly)

应该(NSRange正确使用)

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

but it can actually be just

但它实际上可以只是

return 6;

or if the range length is a parameter

或者如果范围长度是一个参数

return length;

Again, there's no need in the world to slice an array and count. The length is known a priori.

同样,世界上没有必要对数组进行切片和计数。长度是先验已知的。



So in the context of UITableViewDataSource, you have to

因此,在 的上下文中UITableViewDataSource,您必须

  • return the count for each section in -tableView:numberOfRowsInSection:. Something like

    switch(section) {
        case 0: return 2;
        case 1: return 18;
    }    
    
  • return the actual objects in tableView:cellForRowAtIndexPath:. Something like

    id object = nil;
    switch (indexPath.section) {
        case 0:
            object = self.objects[indexPath.row];
            break;
        case 1:
            object = self.objects[2 + indexPath.row];
            break;
    }
    ...
    
  • 返回 中每个部分的计数-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;
    }
    ...
    


As an extra tip, I would advice using a different notation for building structs

作为额外的提示,我建议使用不同的符号来构建结构

NSMakeRange(0, 42)

can be written

可以写

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

which is much more readable (and less error prone, especially when you are in doubt about the meaning of the parameters).

这更具可读性(并且更不容易出错,尤其是当您对参数的含义有疑问时)。

Even

甚至

(NSRange){ 0, 42 }

is acceptable. I think it's better (and shorter) than NSMakeRange, but it loses the benefits or readability.

是可以接受的。我认为它比 更好(也更短)NSMakeRange,但它失去了好处或可读性。

回答by Anton

Ok I have solve my issue

好的,我已经解决了我的问题

In my Fetcher class I did

在我的 Fetcher 课上,我做了

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

then

然后

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

then in method cellForRowAtIndexPath:

然后在方法 cellForRowAtIndexPath 中:

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

item - it's my NSObject with MVC

item - 这是我的 MVC 的 NSObject

So It's working As I wanted :)

所以它按我的意愿工作:)

Thanks for all trying to help me.

感谢所有试图帮助我的人。

Cheers

干杯