簡體   English   中英

NSRangeException錯誤

[英]NSRangeException Error

我正在嘗試從JSON解析對象后填充表格視圖。 我想將行數設置為已分析對象的數量。

這是我的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.要求之前2013-08-06 23:53:04.023 NotificationReader [1193:c07] 2. json parshing操作已開始2013-08-06 23:53 :04.031 NotificationReader [1193:c07] 3.輸入numberOfRowsInSection塊2013-08-06 23:53:04.040 NotificationReader [1193:c07]無通知2013-08-06 23:53:04.319 NotificationReader [1193:c07] 3。輸入了numberOfRowsInSection塊2013-08-06 23:53:04.320 NotificationReader [1193:c07]共有14條通知2013-08-06 23:53:08.260 NotificationReader [1193:c07] *由於未捕獲的異常而終止應用程序

因此,首先認為我的數組為空,然后重新加載並正確獲取通知計數。 不幸的是,它永遠不會進入cellForRowAtIndexPath方法。

更新3

我已經在項目中添加了一個異常斷點,並進行了一些額外的日志記錄,我假設它在某種程度上無法重新加載表視圖。 到目前為止,結果如下:

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成功塊中的主線程上調用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]);
}];

評論者是正確的,您應該通過設置斷點並單步執行代碼來調試這種事情。 用日志語句補充此方法。

您還應該在Xcode中設置“所有異常斷點”(命令6,然后單擊左下方的+按鈕)。

該錯誤可能沒有在numberOfRowsInSection發生。 它可能發生在您執行的cellForRowAtIndexPath中:

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

就像您在numberOfRowsInSection執行nilcount檢查一樣,您應該在此處執行相同的操作:

if (self.notifications) {
    if (indexPath.row < [self.notifications count]) {
        NSDictionary *notification = [[self notifications] objectAtIndex:[indexPath row]];`
        //...
    }
}

我的猜測是JSON響應不是您期望的,因此self.notifications不是您期望的。

在不同的機器上運行代碼后,一切似乎都可以正常工作。 我的配置中肯定有一些垃圾,因此我再次添加了該項目,並可以確認它正在運行。 謝謝大家的回應! @Sam,特別感謝您的測試和耐心!

Oh Sam的回答非常好,但是即使我做他提到的所有事情對我也不起作用,直到我意識到我的Table view Storyboard中的 Content設置為Static Cells而不是Dynamic Prototypes 動態的原型表視

即使您這樣定義自己的numberOfRowsInSection

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

如果它不是動態的,則可能會失敗;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM