【发布时间】:2015-03-27 09:22:46
【问题描述】:
我在保存UITableViewCell 的状态时遇到问题,不知道如何解决。希望有人可以帮助我。
解释:
服务器上有一个 API,我从中获取数据,然后将其存储在 NSMutableArray 中。数组的每个对象都包含属性ready,可以是1 或0。所以我用这个数据填充UITableView没有问题,但不是每个数据对象都准备好了(即0),我需要在服务器上获得完成进度,然后在每个单元格中显示它是需要的。我在UITableViewCell 的动态原型中拥有UIProgressView,并在获得后设置进度。如果这样的“未准备好”对象只有一个,则没有问题。但是,如果有很多对象,我就无法显示进度并且我不明白为什么。
这是我的代码。
cellForRowAtIndexPath 方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"readyCell";
AVMMovieCell *cell = [self.readyTable dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = (AVMMovieCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
AVMFilmsStore *oneItem;
oneItem = [readyArray objectAtIndex:indexPath.row];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if (oneItem.ready==1){
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
if ([selecedCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]] )
{
if (![cell.progressLabel.text isEqualToString:@""]&& ![cell.progressLabel.text isEqualToString:@"Success"] && ![cell.progressLabel.text isEqualToString:@"Creating"]){
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
} else {
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
}
}
else{
if(!oneItem.isProcessing && !cell.selected){
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
}
}
} else { //if processing
if (![processingCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]){
[processingCellsArray addObject:[NSString stringWithFormat:@"%@",rowNsNum]];
if (!cell.isSelected){
[cell setSelected:YES];
}
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
NSArray * arrayOfThingsIWantToPassAlong =
[NSArray arrayWithObjects: cell, oneItem, indexPath, nil];
if(!isMaking){
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0];
} else{
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0.5];
}
isMaking = YES;
} else {
if (!cell.isSelected){
[cell setSelected:YES];
}
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
NSArray * arrayOfThingsIWantToPassAlong =
[NSArray arrayWithObjects: cell, oneItem, indexPath, nil];
if(!isMaking){
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0];
} else{
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0.3];
}
isMaking = YES;
}
}
return cell;
}
和getProgress方法:
-(void)getProgress:(NSArray*)args{
if (progManager == nil && !progStop){
__block AVMFilmsStore * oneItem = args[1];
if(!oneItem.isLocal){
__block AVMMovieCell * cell = args[0];
__block NSIndexPath *indexPath = args[2];
progManager = [AFHTTPRequestOperationManager manager];
__block NSString *token = [defaults objectForKey:@"token"];
__block NSString *header = [NSString stringWithFormat:@"Bearer %@",token];
__block NSDictionary *params = @{@"lang": NSLocalizedString(@"lang",nil),@"project":oneItem.fileId};
__block NSString *oneHundredPercent;
__block NSString *progIsText;
progManager.responseSerializer = [AFJSONResponseSerializer serializer];
[progManager.requestSerializer setValue:header forHTTPHeaderField:@"Authorization"];
if(cell.selected || isMaking) { //if I just check for "cell.selected" is always "NO"
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[progManager POST:@"http://example.com/api/project/get-progress" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([[responseObject objectForKey:@"result"]isEqualToString:@"success"]){
progCreate = [responseObject objectForKey:@"progress"];
oneHundredPercent = @"100";
if ([progCreate intValue]==[oneHundredPercent intValue]){
if([processingCellsArray containsObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]]){
[processingCellsArray removeObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]];
[cell setSelected:NO];
}
[readyArray removeAllObjects];
[defaults setObject:@"false" forKey:@"isSomethingInSort"];
isMaking = NO;
[self getReadyMovies:progIsText nameLabel:oneItem.fileName];
} else{
if([progCreate intValue]>=50){
if([progCreate intValue]>=60){
self.navigationController.navigationItem.leftBarButtonItem.enabled = YES;
createMainButton.enabled = YES;
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"gotFiftyNote" object:@"50"];
[cell.progressLine setProgress:[progCreate floatValue]/100 animated:YES];
} else {
[cell.progressLine setProgress:progUploadLimit];
}
progManager = nil;
progManager.responseSerializer = nil;
progManager.requestSerializer = nil;
token = nil;
header = nil;
params = nil;
progIsText = nil;
oneItem = nil;
cell = nil;
indexPath = nil;
isMaking = YES;
progCreate = nil;
oneHundredPercent = nil;
[self getProgress:args];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(@"Error: %@", error.localizedDescription);
}];
}
}
}
}
任何建议都会对我有所帮助。我为这个问题头疼了两周。
【问题讨论】:
-
您需要重构此代码并接受面向对象。使单元负责更新自身。
performSelector几乎总是一种代码气味。您还会遇到问题,因为您正在从后台处理程序更新 UI,以及对 NSMutableArray 进行非线程安全更新的潜在问题 -
几天前我遇到了同样的问题。检查 Rob 的评论和 Aaron 的示例。可能对你有帮助:link
标签: ios objective-c iphone uitableview