我的第一个 iPad 应用程序中有上述 CoreData 模型。我正在 TableViewController 中构建过滤系统,如下所示。问题是,每当我进行 UI 更改时,切换点击按钮的开关,我的 UI 会在一两秒内变得无响应。我运行了一个非常长的函数,它重新创建照片的获取请求,然后运行更多计数获取以确定是否应该启用控件。我只是不知道如何以有意义的方式将其分开以防止挂起。即使我需要添加一秒钟左右的旋转视图,我也很满意。只是想摆脱滞后。
正如我所提到的,这是我第一次尝试 iOS 开发,所以我将不胜感激任何建议......
-(void) refilterPhotos {
/*
* First section builds the NSCompoundPredicate to use for searching my CoreData Photo objects.
Second section runs queries so 0 result controls can be disabled.
*/
subpredicates = [[NSMutableArray alloc] init];
NSPredicate *isNewPredicate;
if(newSwitch.on) {
isNewPredicate = [NSPredicate predicateWithFormat:@"is_new == 1"];
} else {
isNewPredicate = [NSPredicate predicateWithFormat:@"is_new == 0"];
}
[subpredicates addObject:isNewPredicate];
//Photo Types
PhotoType *photoType;
NSPredicate *photoTypePredicate;
for (UISwitch *photoSwitch in photoSwitches) {
PhotoType * type = (PhotoType *) photoSwitch.property;
if([type.selected boolValue] == YES) {
NSLog(@"photo_type.label == %@", type.label);
photoType = type;
photoTypePredicate = [NSPredicate predicateWithFormat:@"photo_type.label == %@", type.label];
break;
}
}
//Feed Types
FeedType *feedType;
NSPredicate *feedTypePredicate;
for (UISwitch *feedSwitch in feedSwitches) {
FeedType * type = (FeedType *) feedSwitch.property;
if([type.selected boolValue] == YES) {
NSLog(@"feed_type.label == %@", type.label);
feedType = type;
feedTypePredicate = [NSPredicate predicateWithFormat:@"feed_type.label == %@", type.label];
break;
}
}
//Markets
NSArray *filteredMarkets = [model.availableMarkets filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"selected == 1"]];
for (Market *market in filteredMarkets) {
[subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY markets.name == %@", market.name]];
}
//Tags
NSArray *filteredTags = [model.availableTags filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"selected == 1"]];
for (Tag *tag in filteredTags) {
NSLog(@"ANY tags.name == %@",tag.name);
[subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY tags.name == %@", tag.name]];
}
if(photoTypePredicate)
[subpredicates addObject:photoTypePredicate];
if(feedTypePredicate)
[subpredicates addObject:feedTypePredicate];
NSPredicate *finished = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];//Your final predicate
model.availablePhotos = [model fetchPhotoswithPredicate:finished];
[[self parentViewController] setTitle:[NSString stringWithFormat:@"%d items",[model.availablePhotos count]]];
NSLog(@"FILTERED PHOTOS:::: %d", [model.availablePhotos count]);
[gridVC reloadGrid];
/**
* Filtering Section Here, I'm running count requests for each grouping of controls to ensure if they're selected, results will be returned.
* If zero results, I'll disable that control. For the switch-based controls, I need to removed them before running my fetches since there can only be
* one switch value per photo.
*/
//Have to remove the existing type predicate since they're exlcusive values
[subpredicates removeObject:isNewPredicate];
//New Toggle
NSPredicate *newRemainderPredicate = [NSPredicate predicateWithFormat:@"is_new == %d",newSwitch.on?0:1];
[subpredicates addObject:newRemainderPredicate];
if([model countPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]]<1) {
[newSwitch setEnabled:NO];
} else {
[newSwitch setEnabled:YES];
}
[subpredicates removeObject:newRemainderPredicate];
[subpredicates addObject:isNewPredicate];
[subpredicates removeObject:photoTypePredicate];
//Photo Type Toggles
NSArray *remainderPhotoTypes = [photoSwitches filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"on == NO"]];
for( UISwitch*control in remainderPhotoTypes) {
PhotoType *remainderPhotoType = (PhotoType*)control.property;
[subpredicates addObject:[NSPredicate predicateWithFormat:@"photo_type == %@", remainderPhotoType]];
if([model countPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]]<1) {
//NSLog(@"PHOTOTYPE OFF %@", remainderPhotoType.label);
control.enabled = NO;
} else {
//NSLog(@"PHOTOTYPE ON %@ count = %d", remainderPhotoType.label, [[model fetchPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]] count]);
control.enabled = YES;
}
remainderPhotoType.enabled = [NSNumber numberWithBool:control.enabled];
[subpredicates removeObject:[NSPredicate predicateWithFormat:@"photo_type == %@", remainderPhotoType]];
}
if(photoTypePredicate)
[subpredicates addObject:photoTypePredicate];
[subpredicates removeObject:feedTypePredicate];
//Feed Type Toggles
NSArray *remainderFeedTypes = [feedSwitches filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"on == NO"]];
for( UISwitch*control in remainderFeedTypes) {
PhotoType *remainderFeedType = (PhotoType*)control.property;
[subpredicates addObject:[NSPredicate predicateWithFormat:@"feed_type == %@", remainderFeedType]];
if([model countPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]]<1) {
control.enabled = NO;
} else {
control.enabled = YES;
}
remainderFeedType.enabled = [NSNumber numberWithBool:control.enabled];
[subpredicates removeObject:[NSPredicate predicateWithFormat:@"feed_type == %@", remainderFeedType]];
}
if(feedTypePredicate)
[subpredicates addObject:feedTypePredicate];
NSArray *remainderMarkets = [[model availableMarkets] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"selected == 0"]];
//Markets..many-to-many so I don't remove the existing predicate
for( Market *remainderMarket in remainderMarkets) {
[subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY markets == %@", remainderMarket]];
NSInteger countForTag = [model countPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]];
if(countForTag<1) {
remainderMarket.enabled = [NSNumber numberWithInt:0];
} else {
remainderMarket.enabled = [NSNumber numberWithInt:1];
}
[subpredicates removeObject:[NSPredicate predicateWithFormat:@"ANY markets == %@", remainderMarket]];
}
NSArray *remainderTags = [[model availableTags] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"selected == 0"]];
//TAGS..many-to-many so I don't remove the existing predicate
int tagCounter = 0;
for( Tag *remainderTag in remainderTags) {
[subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY tags == %@", remainderTag]];
NSInteger countForTag = [model countPhotoswithPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]];
if(countForTag<1) {
NSLog(@"TAG OFF %@", remainderTag.name);
remainderTag.enabled = 0;
} else {
NSLog(@"TAG ON %@ count = %d", remainderTag.name, countForTag);
remainderTag.enabled = [NSNumber numberWithInt:1];
}
[subpredicates removeObject:[NSPredicate predicateWithFormat:@"ANY tags.name == %@", remainderTag.name]];
tagCounter ++;
}
//Update the controls with this new data
[self.tableView reloadData];
}