当我滚动到TableView的底部时,我收到此错误,我不认为实际从服务器检索图片有任何错误。:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (15) beyond bounds (15)'
这是我的.m文件,我将其剪切为文件中实际需要的部分:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self entries] count] + tweets.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 2 == 0) {
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *created = [tweet objectForKey:@"created_at"];
NSLog(@"%@", created);
static NSString *CellIdentifier = @"TweetCell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *text = [tweet objectForKey:@"text"];
NSString *name = [[tweet objectForKey:@"user"] objectForKey:@"name"];
cell.textLabel.text = text;
cell.detailTextLabel.text = [NSString stringWithFormat:@"by %@", name];
return cell;
}else {
static NSString *CellIdentifier = @"InstagramCell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *entry = [self entries][indexPath.row];
NSString *imageUrlString = entry[@"images"][@"low_resolution"][@"url"];
NSURL *url = [NSURL URLWithString:imageUrlString];
[cell.imageView setImageWithURL:url];
return cell;
}
}
- (void)fetchTweets {
self.twitterClient = [[AFOAuth1Client alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.twitter.com/1.1/"] key:@"TWEETER_KEY" secret:@"TWEETER_SECRET"];
[self.twitterClient authorizeUsingOAuthWithRequestTokenPath:@"/oauth/request_token" userAuthorizationPath:@"/oauth/authorize" callbackURL:[NSURL URLWithString:@"floadt://success"] accessTokenPath:@"/oauth/access_token" accessMethod:@"POST" scope:nil success:^(AFOAuth1Token *accessToken, id responseObject) {
[self.twitterClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self.twitterClient getPath:@"statuses/home_timeline.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *responseArray = (NSArray *)responseObject;
[responseArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"Success: %@", obj);
tweets = responseArray;
[self.tableView reloadData];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
} failure:^(NSError *error) {
NSLog(@"Error: %@", error);
}];
}
答案 0 :(得分:1)
numberOfRowsInSection
的返回值与代码在cellForRowAtIndexPath
中执行的数组访问之间需要紧密协调。
考虑到这一点,你的条目数组和推文数组都有4个元素。所以numberOfRowsInSection
返回8.调用cellForRowAtIndexPath方法来配置第6行。您的代码将执行此操作:NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
但等等......那个数组只有4个元素,对吧?在索引6处询问某些内容会产生您看到的崩溃。
编写将数组交错为单个数组的方法可能更简单,然后在numberOfRowsInSection
中回答组合数组的计数。在cellForRowAtIndexPath
中,数组元素本身应该能够告诉您具有哪种行(而不是索引)。取消引用组合数组并相应地配置表。
编辑 - 我会尝试在代码中更明确地提出我的建议:让我们说,为简单起见,“条目”和“推文”都是NSDictionaries的数组,并且您的应用程序希望首先在UI条目中组织它们,然后推文。
//在界面中:
@property (nonatomic, strong) NSArray *myModel;
//代码:
- (NSArray *)myModel {
if (!_myModel) {
NSMutableArray *array = [NSMutableArray arrayWithArray:[self entries]];
[array addObjectsFromArray:tweets];
_myModel = [NSArray arrayWithArray:array];
}
return _myModel;
}
我们称之为“myModel”是有原因的。它是表的数据源。数据源协议明确要求该数组(而不是其他数据)。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.myModel.count;
}
现在,cellForRowAtIndexPath将要求您配置多个(myModel计数)行,编号为0..count-1。您必须为所有数据源方法取消引用相同的数组 - myModel:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *myModelForThisRow = self.myModel[indexPath.row];
// get the cell = deque...
cell.textLabel.text = myModelForThisRow[@"someKey"];
return cell;
}
如果您的推文或条目数组发生变化怎么办?没问题,只需重建这样的模型:
- (IBAction)tweetsOrEntriesDidChange:(id)sender {
self.myModel = nil; // the "lazy" getter will rebuild it
[self.tableView reloadData]; // this will call the datasource which will call the lazy getter
}
答案 1 :(得分:0)
你正试图在它的界限之外读入一个数组。
该阵列访问看起来非常可疑
if (indexPath.row % 2 == 0) {
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
以及这个
NSDictionary *entry = [self entries][indexPath.row];
从我看到的数组tweets
和[self entries]
中,每个对象都不包含与表格部分中的行一样多的对象。
我从这里接受了我的意见:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self entries] count] + tweets.count;
}
答案 2 :(得分:0)
NSRangeException
是因为您尝试访问的索引不在数组的有效范围内。尝试在Xcode中设置“异常断点”以查看它的来源。检查here以了解有关异常断点的更多信息
这通常是由 off by one 错误引起的。