2014-06-09 1 views
2

프로그래밍 방식으로 내 MatchCenterViewController 내에 UITableView를 만들었지 만 클라우드 코드 함수에서 반환되는 JSON 데이터로 채워지지 않는 것 같습니다. 이 충돌하고 나에게 다음과 같은 오류 제공 :UITableView 배열에서 '빈 배열의 경계를 넘어선 인덱스 0'을 반환합니다.

내가 무엇을 이해할 수에서
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" 
     } 
    ] 
} 

답변

4

당신의 API 호출이 데이터를 반환하기 전에 jQuery과 셀을 요청합니다. 네트워크 요청은 오랜 시간이 걸릴 수 있으며 사용자가 네트워크에 연결되어 있지 않으면 완전히 실패합니다. 네트워크 통화가 즉시 반환된다고 가정하지 마십시오.

그리고 비동기 (!) API 호출을 viewDidAppear:에서만 시작하기 때문에 tableView는 API 호출을 시작하기 전에도 셀을 요청하기 시작합니다. 당신이 액세스하려고 tableView:cellForRowAtIndexPath: 첫 번째 섹션에서 3 개 행이 있음을 지정한 이후

:

배열이 비어 있기 때문에 경계 부족 예외를 제기하고,에 객체가없는
// 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]; 
} 
을3210

하고, 다음 충돌을 방지하려면 self.matchCenter이있는 tableView의 ALLOC 초기화 후, 즉를 nil이없는 장소에 셀을 등록 전화를 이동합니다.

예컨대 :

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

은 또한, 나는 그가'UITableView'에 무기 호 참조에 셀을 등록하고 다음 시간 이후에 테이블 뷰를 인스턴스화로 그 세포를 dequeueing으로 나중에 문제가있을 것으로 판단된다. –

관련 문제