iphone - NSRangeException 错误

标签 iphone ios objective-c

我试图在从 JSON 解析对象后填充 TableView 。我想将行数设置为已解析对象的计数。

这是我的 viewDidLoad 代码:

    - (void)viewDidLoad
{
[super viewDidLoad];

// initializing data source
[self setNotifications:[[NSMutableArray alloc] init]];

NSURL *url = [NSURL URLWithString:SourceURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];


AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

    [self setNotifications:[JSON objectForKey:@"notifications"]];
    //  [[self tableView] setHidden:NO];
    [[self tableView] reloadData];



} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Request Failure Because %@",[error userInfo]);
}];

[operation start];

这是我的一种数据源方法(我相信错误一定在这里):

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([self notifications] && [[self notifications] count] ) {
        return [[self notifications] count];
    } else{
        return 0;
    }
}

这是我的完整错误信息:

> *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 ..
> 0]'
> *** First throw call stack: (0x13c4012 0x118ce7e 0x1379b44 0x510c04 0x300ea0 0x2b5c4e 0x2b8224 0x17c952 0x17c2dc 0xc4a9d14 0x26e0 0x16ea2
> 0x18409 0x162753f 0x1639014 0x16297d5 0x136aaf5 0x1369f44 0x1369e1b
> 0x22647e3 0x2264668 0xd0ffc 0x1f1d 0x1e45) libc++abi.dylib: terminate
> called throwing an exception

更新:

这是我的 cellForRowAtIndexpath 方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"readNotification";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (!cell){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
    }

    NSDictionary *notification = [[self notifications] objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[notification objectForKey:@"from"]];
    [[cell detailTextLabel] setText:[notification objectForKey:@"date"]];
    return cell;
}

更新 2

我在项目中添加了一些日志,它提供了一些有趣的输出:

2013-08-06 23:53:03.994 NotificationReader[1193:c07] 1. before request 2013-08-06 23:53:04.023 NotificationReader[1193:c07] 2. json parshing operation started 2013-08-06 23:53:04.031 NotificationReader[1193:c07] 3. entered the numberOfRowsInSection block 2013-08-06 23:53:04.040 NotificationReader[1193:c07] No notifications 2013-08-06 23:53:04.319 NotificationReader[1193:c07] 3. entered the numberOfRowsInSection block 2013-08-06 23:53:04.320 NotificationReader[1193:c07] There were 14 notifications 2013-08-06 23:53:08.260 NotificationReader[1193:c07] * Terminating app due to uncaught exception

所以首先它认为我的数组是空的,然后它重新加载并获得正确的通知计数。不幸的是,它从未进入 cellForRowAtIndexPath 方法..

更新 3

我在我的项目中添加了一个异常断点,并做了一些额外的日志记录,我假设它在重新加载 TableView 时遇到了问题。这是目前的结果:

2013-08-07 08:40:58.104 NotificationReader[433:c07] 1. before request
2013-08-07 08:40:58.107 NotificationReader[433:c07] 2. json parshing operation started
2013-08-07 08:40:58.113 NotificationReader[433:c07] 3. entered the numberOfRowsInSection block
2013-08-07 08:40:58.120 NotificationReader[433:c07] Found 0 notifications!
2013-08-07 08:41:10.852 NotificationReader[433:c07] Trying to reload data
2013-08-07 08:41:10.853 NotificationReader[433:c07] data needs to be reloaded
2013-08-07 08:41:10.854 NotificationReader[433:c07] 3. entered the numberOfRowsInSection block
2013-08-07 08:41:10.855 NotificationReader[433:c07] Found 14 notifications!
2013-08-07 08:41:10.858 NotificationReader[433:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x13c5012 0x118de7e 0x137ab44 0x511c04 0x301ea0 0x2b6c4e 0x2b9224 0x17d952 0x17d2dc 0xc4c0d14 0x351b 0x162853f 0x163a014 0x162a7d5 0x136baf5 0x136af44 0x136ae1b 0x22657e3 0x2265668 0xd1ffc 0x2c4d 0x2b75)
libc++abi.dylib: terminate called throwing an exception}

堆栈跟踪:

#0  0x0118de52 in objc_exception_throw ()
#1  0x0137ab44 in -[__NSArrayI objectAtIndex:] ()
#2  0x00511c04 in -[UITableViewDataSource tableView:heightForRowAtIndexPath:] ()
#3  0x00301ea0 in -[UITableViewController tableView:heightForRowAtIndexPath:] ()
#4  0x002b6c4e in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] ()
#5  0x002b9224 in -[UITableViewRowData numberOfRows] ()
#6  0x0017d952 in -[UITableView noteNumberOfRowsChanged] ()
#7  0x0017d2dc in -[UITableView reloadData] ()
#8  0x0c4a9d14 in -[UITableViewAccessibility(Accessibility) reloadData] ()
#9  0x0000351b in __36-[NRTableViewController viewDidLoad]_block_invoke_2 at /Users/jozsef/Development/NotificationReader/NotificationReader/NRTableViewController.m:52

我尝试使用 lldb 得到这个结果:

(lldb) po [[self notifications] count]
error: Execution was interrupted, reason: Attempted to dereference an invalid pointer..
The process has been returned to the state before execution.

最佳答案

这是由于试图访问超出数组边界的索引造成的。从表面上看,唯一的数组访问是在 -tableView:cellForRowAtIndexPath::

NSDictionary *notification = [[self notifications] objectAtIndex:[indexPath row]];

我希望这是引发异常的地方。

您可以通过从断点导航器中添加“添加异常断点...”来确定。

通过确认 [indexPath row][self notifications] 数组的范围内来解决这个问题。或者,如果您希望它始终在范围内,那么找出它可能超出范围的原因。

附带说明,您可以按如下方式重写您的方法之一:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.notifications count];
}

如果 self.notifications 是 nil,这将返回 0。如果 count 是 0,那么它显然会返回 0。这就是所有需要的。

编辑:最后,您还可以使用下标重写数组访问,如下所示:

NSDictionary *notification = self.notifications[indexPath.row];

确保在 AFJSONRequestOperation 的成功 block 中调用主线程上的 UI 更新,即

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

    // update on the main thread!
    dispatch_async(dispatch_get_main_queue(), ^{
        [self setNotifications:[JSON objectForKey:@"notifications"]];
        //  [[self tableView] setHidden:NO];
        [[self tableView] reloadData];
    });        

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Request Failure Because %@",[error userInfo]);
}];

关于iphone - NSRangeException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18090424/

相关文章:

ios - iOS SDK 中的 MDM iPCU 配置文件安装失败

iPhone : JSON message not creating correctly

ios - 如何替换捆绑文件的内容

ios - CBPeripheral 连接在调用 discoverServices 后保持断开连接

ios - objective-c : Resizing a UIImageView

ios - UITableview CommitEditingStyle 具有多个按钮?

ios - 使用 Fabric 在 IOS 10.2 中登录 Twitter 时获取个人资料图片和更多信息等详细信息

css - 带有 iOS7 的 iPhone 在横向模式下不显示文档的全高

ios - 为什么在Braintree手动集成上出现找不到“Braintree/BTUICTAControl.h”文件的错误?

ios:如果 View 消失,如何正确处理请求回调