我在objective-c中非常新,我试图做一个UItableview应用程序。整个概念是我有两个视图,两个是tableviews。在第一个视图控制器中,我有几个月,具体取决于你按下哪个月我在第二个视图控制器中更改一个整数(int currentMonth)。在第二个视图控制器中,我想要呈现动物的表格视图。动物应该只显示它们是否“可以捕获”并且还显示它们“可以捕获”多长时间,并且我已经为此编写了代码并且它有效。
问题在于,使用我当前的代码,我将对象从animalArray中删除,并在cellForRowAtIndexPath中重新加载tableview的数据,这使得滚动速度非常慢。
我试图提出其他解决方案,但到目前为止还没有运气,所以我希望有人可以把我推向正确的方向。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"DjurCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//skapar en variabel av Appdelegate för att komma åt arrayen med djur.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];
UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
cellBackgroundView.image = background;
cell.backgroundView = cellBackgroundView;
if (cell== nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}
//Skapar en label och länkar den med storyboard.
UILabel *animalNameLabel = (UILabel *)[cell viewWithTag:104];
UILabel *animalDetailLabel = (UILabel *)[cell viewWithTag:102];
NSString *strmonth;
switch (self.currentMonth) {
case 0:
strmonth=@"Juli";
break;
case 1:
strmonth=@"Augusti";
break;
case 2:
strmonth=@"September";
break;
case 3:
strmonth=@"Oktober";
break;
case 4:
strmonth=@"November";
break;
case 5:
strmonth=@"December";
break;
case 6:
strmonth=@"Januari";
break;
case 7:
strmonth=@"Februari";
break;
case 8:
strmonth=@"Mars";
break;
case 9:
strmonth=@"April";
break;
case 10:
strmonth=@"Maj";
break;
case 11:
strmonth=@"Juni";
break;
case 12:
strmonth=@"Juli";
break;
default:
break;
}
//Algoritm för utskrivandet av hur lång tid en art är jaktbar. Om nuvarande månad är större än jaktstarten och mindre än jaktstoppet.
if ((self.currentMonth>[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstartmonth])&&(self.currentMonth<[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstopmonth])) {
animalNameLabel.text = [[appDelegate.animalArray objectAtIndex:indexPath.row]getArt];
animalDetailLabel.text = @"Jaktbar hela månaden";
}
//Om nuvarande månad är lika med jaktstarten.
else if(self.currentMonth==[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstartmonth]){
animalNameLabel.text = [[appDelegate.animalArray objectAtIndex:indexPath.row]getArt];
animalDetailLabel.text = [NSString stringWithFormat:@"Jaktbar från och med den %i:e %@",[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstartday],strmonth];
}
//Om nuvarande månad är lika med jaktstoppet.
else if(self.currentMonth==[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstopmonth]){
animalNameLabel.text = [[appDelegate.animalArray objectAtIndex:indexPath.row]getArt];
animalDetailLabel.text = [NSString stringWithFormat:@"Jaktbar till och med den %i:e %@",[[appDelegate.animalArray objectAtIndex:indexPath.row]getjaktstopday],strmonth];
}
//I övriga fall
else{
animalNameLabel.text = [[appDelegate.animalArray objectAtIndex:indexPath.row]getArt];
animalDetailLabel.text = [NSString stringWithFormat:@"Ej Jaktbar"];
}
//这就是滚动速度慢的原因。
if ([animalDetailLabel.text isEqual:@"Ej Jaktbar"]) {
[appDelegate.animalArray removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
return cell;
}
我应该如何更改代码?
答案 0 :(得分:2)
永远不要从cellForRowAtIndexPath中调用重装数据。 那是什么意思?
我不认为从该阵列中删除“驱动”表内容的字段是个好主意。您可以在不重新加载数据的情况下执行此操作,但您必须期望表格请求您在阵列中没有相应索引的单元格。
但是,当你用一些更合适的方法(viewDidLoad?)更改数据时,你会好得多。您可以强制该表从重新加载过程未调用的任何方法重新加载其数据。由于重新加载,将调用所有数据源方法。
如果您的代码略有不同,那么您可能会冒无限循环。在你的情况下它不是infinte,因为你只是删除你的数组中的“Ej Jaktbar”的所有发生,这是有限的。但是对于每一次发生,你都会一次又一次地重新加载表格。将从单元格0开始一次又一次地调用cellForRorAtIndexPath。但是您的表没有机会释放未使用的单元格。我猜你甚至会为细胞视图留下很多记忆,因为你从未真正使用过。
答案 1 :(得分:0)
你可以使用这种方法:
免责声明 - 这是伪思想库,它也是在没有IDE的情况下编写的。所以它有风险它根本无法工作或编译。
在viewDidLoad()
的{{1}}内,您可以执行以下操作:
animalTableViewController
AppDelegate中的功能可能看起来像这样:
从你的情况看,它取决于它是哪个月,所以你可能需要在这里获得当月。哪个可以从-(void)viewDidLoad
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
// it would be nice to get the month here. You could probably get it from a custom init of the viewController.
[appDelegate removeNonHuntableAnimalsFromDatasourceWithMonth:self.Month];
// the rest of your code
}
viewDidLoad
发送
animalViewController
如果结构看起来如下所示:
-(void)removeNonHuntableAnimalsFromDatasourceWithMonth:(NSString *)month
{
// iterate through all animals
for (animalObject *animal in self.animalArray)
{
// if the month is lesser than the start or greater than the stop.
// calling [property intValue] can be done if the properties are of the type NSString
if ([month intValue] < [animal.jaktStart intValue] || [month.intValue] > [animal.jaktStopp intValue])
{
// remove the animal from the datasource
[self.animalArray removeObject:animal];
}
}
}
因此,如果您的数据源看起来像上面的结构,则循环将在第11个月将结构修改为以下内容。
animalArray[0] = [AnimalObject]
(jaktStart) = 5
(jaktStopp) = 6
(art) = Duck
animalArray[1] = [AnimalObject]
(jaktStart) = 1
(jaktStopp) = 8
(art) = Moose
animalArray[2] = [AnimalObject]
(jaktStart) = 11
(jaktStopp) = 12
(art) = Wolf
animalArray[3] = [AnimalObject]
(jaktStart) = 2
(jaktStopp) = 4
(art) = Polarbear
免责声明此代码可能会也可能根本不起作用!希望它能给你一些想法。