【问题标题】:UITableView array returning error 'index 0 beyond bounds for empty array'UITableView 数组返回错误“空数组的索引 0 超出范围”
【发布时间】:2014-07-29 12:50:24
【问题描述】:

我已经在我的 MatchCenterViewController 中以编程方式创建了一个 UITableView,但它似乎没有填充我的云代码函数返回的 JSON 数据。它崩溃并给我以下错误:

2014-06-08 20:56:23.762 Parse+Storyboard[9136:607] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(
    0   CoreFoundation                      0x02a8c1e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x0264a8e5 objc_exception_throw + 44
    2   CoreFoundation                      0x02a408b2 -[__NSArrayI objectAtIndex:] + 210
    3   Parse+Storyboard                    0x00005e6a -[MatchCenterViewController tableView:cellForRowAtIndexPath:] + 218
    4   UIKit                               0x0140311f -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 412
    5   UIKit                               0x014031f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
    6   UIKit                               0x013e4ece -[UITableView _updateVisibleCellsNow:] + 2428
    7   UIKit                               0x013f96a5 -[UITableView layoutSubviews] + 213
    8   UIKit                               0x01379964 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
    9   libobjc.A.dylib                     0x0265c82b -[NSObject performSelector:withObject:] + 70
    10  QuartzCore                          0x0064f45a -[CALayer layoutSublayers] + 148
    11  QuartzCore                          0x00643244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    12  QuartzCore                          0x006430b0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
    13  QuartzCore                          0x005a97fa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
    14  QuartzCore                          0x005aab85 _ZN2CA11Transaction6commitEv + 393
    15  QuartzCore                          0x006685b0 +[CATransaction flush] + 52
    16  UIKit                               0x013089bb _UIApplicationHandleEventQueue + 13095
    17  CoreFoundation                      0x02a1577f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    18  CoreFoundation                      0x02a1510b __CFRunLoopDoSources0 + 235
    19  CoreFoundation                      0x02a321ae __CFRunLoopRun + 910
    20  CoreFoundation                      0x02a319d3 CFRunLoopRunSpecific + 467
    21  CoreFoundation                      0x02a317eb CFRunLoopRunInMode + 123
    22  GraphicsServices                    0x02ce95ee GSEventRunModal + 192
    23  GraphicsServices                    0x02ce942b GSEventRun + 104
    24  UIKit                               0x0130af9b UIApplicationMain + 1225
    25  Parse+Storyboard                    0x00002b4d main + 141
    26  libdyld.dylib                       0x038e56d9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

据我所知,它告诉我self.matchCenterArray 是空的,但我似乎无法弄清楚为什么数组没有填充返回的 JSON。

MatchCenterViewController.h:

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"

@interface MatchCenterViewController : UIViewController <UITableViewDataSource>

@property (nonatomic) IBOutlet NSString *itemSearch;

@property (nonatomic, strong) NSArray *imageURLs;
@property (strong, nonatomic) NSString *matchingCategoryCondition;
@property (strong, nonatomic) NSString *matchingCategoryLocation;
@property (strong, nonatomic) NSNumber *matchingCategoryMaxPrice;
@property (strong, nonatomic) NSNumber *matchingCategoryMinPrice;

@property (strong, nonatomic) NSArray *matchCenterArray;

@end

MatchCenterViewController.m:

#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>

@interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UITableView *matchCenter;
@end

@implementation MatchCenterViewController



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
//        self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
//        _matchCenter.dataSource = self;
//        _matchCenter.delegate = self;
//        [self.view addSubview:self.matchCenter];
    }
    return self;



}



- (void)viewDidLoad
{

    [super viewDidLoad];

    [self.matchCenter registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

    self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    _matchCenter.dataSource = self;
    _matchCenter.delegate = self;
    [self.view addSubview:self.matchCenter];

    self.matchCenterArray = [[NSArray alloc] init];


}

- (void)viewDidAppear:(BOOL)animated
{

    self.matchCenterArray = [[NSArray alloc] init];

    [PFCloud callFunctionInBackground:@"MatchCenterTest"
                       withParameters:@{
                                        @"test": @"Hi",
                                        }
                                block:^(NSDictionary *result, NSError *error) {

                                    if (!error) {
                                         self.matchCenterArray = [result objectForKey:@"Top 3"];


                                        dispatch_async(dispatch_get_main_queue(), ^{
                                            [_matchCenter reloadData];
                                        });


                                        NSLog(@"Test Result: '%@'", result);
                                    }
                                }];


}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 3;
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


    NSDictionary *matchCenterDictionary= [self.matchCenterArray objectAtIndex:indexPath.row];

    cell.textLabel.text = [matchCenterDictionary objectForKey:@"Title"];// title of the first object

    //    if([matchCenterDictionary objectForKey:@"Price"] != NULL)
    //    {
    //        cell.detailTextLabel.text = [NSString stringWithFormat:@"$%@",[matchCenterDictionary   objectForKey:@"Price"]];
    //    }

    return cell;


}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}




/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

返回的 JSON:

 {
    "Top 3" : [
        {
            "Title" : "Apple iPhone 5s (Latest Model) - 16GB - Silver (AT&T) Smartphone",
            "Price" : "400.0",
            "Image URL" : "http://thumbs2.ebaystatic.com/m/mewfVG0QbBiu1nZytMuAlZw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5s-Latest-Model-16GB-Silver-AT-T-Smartphone-/181431570117?pt:Cell_Phones"
        },
        {
            "Title" : "Apple iPhone 5c (Latest Model) - 16GB - Pink (Verizon) Smartphone",
            "Price" : "350.0",
            "Image URL" : "http://thumbs4.ebaystatic.com/m/mMPAT67KjfCZF9oorbTf3uw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5c-Latest-Model-16GB-Pink-Verizon-Smartphone-/191204844039?pt:Cell_Phones"
        },
        {
            "Title" : "Apple iPhone 5 16GB, White, works with Virgin Mobile US NEW",
            "Price" : "359.99",
            "Image URL" : "http://thumbs3.ebaystatic.com/m/m5x1uj1iSS2fr691tifrvrw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5-16GB-White-works-Virgin-Mobile-US-NEW-/141227441998?pt:Cell_Phones"
        }
    ]
}

【问题讨论】:

    标签: ios objective-c json uitableview


    【解决方案1】:

    UITableView 将在您的 API 调用返回数据之前请求单元格。网络请求可能需要很长时间,如果用户没有连接到网络,它将完全失败。不要假设您的网络调用会立即返回。

    因为您仅在viewDidAppear: 中启动异步 (!) API 调用,所以 tableView 甚至在您开始 API 调用之前就开始请求单元格。

    由于您已指定第一部分中有 3 行 tableView:cellForRowAtIndexPath: 尝试访问此:

    // for first row
    NSDictionary *matchCenterDictionary= [self.matchCenterArray objectAtIndex:0];
    

    这会引发越界异常,因为您的数组是空的,并且在索引 0 处没有对象。

    如果您的数组中没有 3 个对象,请不要在 tableView:numberOfRowsInSection: 中返回 3,请返回数组中包含的实际对象数:

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

    为了防止下一次崩溃,请将注册单元格的调用移动到 self.matchCenter 不为零的位置,即在 tableView 的 alloc init 之后。

    例如:

    self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    /* ... */
    [self.matchCenter registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    

    【讨论】:

    • 另外,我相信他稍后会在单元格出列时遇到问题,因为他将单元格注册到对 UITableView 的 nil 引用上,然后实例化表格视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多