私が開発しているアプリは、API を介して製品カタログ (約 40,000 製品になります) を取得し、それらを CoreData に解析して、簡単に検索できるようにします。
データの解析を処理するこの方法があり、ダウンロードは完全に意図したとおりに機能します。ダウンロード進行状況バーと処理進行状況バーがあります。ダウンロードは必要に応じて機能しますが、ラベル (または進行状況バー) は処理テキストまたは進行状況のパーセンテージに変わりません。プログラムで確認したところ、正しいラベル テキストがコンソールに出力されますが、ビューには表示されません。
アクティビティ モニターを使用して確認したところ、電話は CPU に関して最大になっています..そのため、オンビューの変更が表示されていないと思います。計算負荷を減らしてプログレスバーを適切に表示する方法はありますか? とにかく、これは効率的なコードとはほど遠いと確信しています。ベストプラクティスなどを知っている段階にはまだ行っていません..
ループ GCD を使用するように変更
GCD を使用するようにコードを変更しましたが、実行時にエラーが発生します: * キャッチされない例外 'NSGenericException' が原因でアプリを終了しています。 '
- (void) processUpdatesBG {
NSArray *jsonArray=[NSJSONSerialization JSONObjectWithData:_responseData options:0 error:nil];
NSArray *products = [jsonArray valueForKey:@"products"];
NSInteger productDBCount = _productDBCount;
productDBCount = 0;
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = delegate.managedObjectContext;
_managedObjectContext = managedObjectContext;
self.totalCount = [products count];
for (id product in products) {
dispatch_queue_t processTheUpdates = dispatch_queue_create("com.app.process_the_updates", 0);
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Products" inManagedObjectContext:_managedObjectContext]];
[request setIncludesSubentities:NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"codes == %@", [product valueForKey:@"product_codes"]];
[request setPredicate:predicate];
dispatch_async(processTheUpdates, ^{
NSError *err;
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&err];
if (results.count == 0){
// Product doesn't exist with code, make a new product
NSLog(@"Product.. %@", [product valueForKey:@"product_name"]);
NSManagedObject* newProduct;
newProduct = [NSEntityDescription insertNewObjectForEntityForName:@"Products" inManagedObjectContext:_managedObjectContext];
[newProduct setValue:[product valueForKey:@"product_name"] forKey:@"name"];
[newProduct setValue:[product valueForKey:@"product_codes"] forKey:@"codes"];
if ([product valueForKey:@"information"] == (id)[NSNull null]){
// No information, NULL
[newProduct setValue:@"" forKey:@"information"];
} else {
NSString *information = [product valueForKey:@"information"];
[newProduct setValue:information forKey:@"information"];
}
} else {
// Product exists, update existing product
for (NSManagedObject *r in results) {
[r setValue:[product valueForKey:@"product_name"] forKey:@"name"];
if ([product valueForKey:@"information"] == (id)[NSNull null]){
// No information, NULL
[r setValue:@"" forKey:@"information"];
} else {
NSString *information = [product valueForKey:@"information"];
[r setValue:information forKey:@"information"];
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{
self.productDBCount = productDBCount + 1;
NSNumber *progress = [NSNumber numberWithFloat:(self.productDBCount / self.totalCount)];
self.downloadUpdateProgress.progress = [progress floatValue];
NSLog(@"Added product");
});
});
}
NSError *error;
if ([self.managedObjectContext save:&error]) {
NSLog(@"Database Updated");
} else {
NSLog(@"Database not Updated, Error: %@", error);
}
self.updateStatus.text = @"Update Completed!";
self.downloadUpdateProgress.hidden = YES;
self.close.hidden = NO;
// NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *now = [[NSDate alloc] init];
// NSString *currentTimestamp = [dateFormatter stringFromDate:now];
// NSLog(@"%@", currentTimestamp);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *apiUpdateTimestamp = [jsonArray valueForKey:@"last_updated"];
[prefs setObject:now forKey:@"last_downloaded_update"];
[prefs setObject:apiUpdateTimestamp forKey:@"api_update_timestamp"];
[prefs synchronize];
// Set the lastDownloadedTimestamp as today
// Set the last
}
オリジナルコード
- (void) processUpdates {
self.updateStatus.text = @"Processing Updates";
self.downloadUpdateProgress.progress = 0;
NSArray *jsonArray=[NSJSONSerialization JSONObjectWithData:_responseData options:0 error:nil];
NSArray *products = [jsonArray valueForKey:@"products"];
NSInteger productDBCount = 0;
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = delegate.managedObjectContext;
_managedObjectContext = managedObjectContext;
NSInteger totalCount = [products count];
for (id product in products) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Products" inManagedObjectContext:_managedObjectContext]];
[request setIncludesSubentities:NO];
NSError *err;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"codes == %@", [product valueForKey:@"product_codes"]];
[request setPredicate:predicate];
NSArray *results = [_managedObjectContext executeFetchRequest:request error:&err];
if (results.count == 0){
// Product doesn't exist with code, make a new product
NSManagedObject* newProduct;
newProduct = [NSEntityDescription insertNewObjectForEntityForName:@"Products" inManagedObjectContext:_managedObjectContext];
[newProduct setValue:[product valueForKey:@"product_name"] forKey:@"name"];
[newProduct setValue:[product valueForKey:@"product_codes"] forKey:@"codes"];
if ([product valueForKey:@"information"] == (id)[NSNull null]){
// No information, NULL
[newProduct setValue:@"" forKey:@"information"];
} else {
NSString *information = [product valueForKey:@"information"];
[newProduct setValue:information forKey:@"information"];
}
} else {
// Product exists, update existing product
for (NSManagedObject *r in results) {
[r setValue:[product valueForKey:@"product_name"] forKey:@"name"];
if ([product valueForKey:@"information"] == (id)[NSNull null]){
// No information, NULL
[r setValue:@"" forKey:@"information"];
} else {
NSString *information = [product valueForKey:@"information"];
[r setValue:information forKey:@"information"];
}
}
}
productDBCount = productDBCount + 1;
NSNumber *progress = [NSNumber numberWithFloat:(productDBCount / totalCount)];
self.downloadUpdateProgress.progress = [progress floatValue];
}
NSError *error;
if ([self.managedObjectContext save:&error]) {
NSLog(@"Database Updated");
} else {
NSLog(@"Database not Updated, Error: %@", error);
}
self.updateStatus.text = @"Update Completed!";
self.downloadUpdateProgress.hidden = YES;
self.close.hidden = NO;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *now = [[NSDate alloc] init];
NSString *currentTimestamp = [dateFormatter stringFromDate:now];
NSLog(@"%@", currentTimestamp);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *apiUpdateTimestamp = [jsonArray valueForKey:@"last_updated"];
[prefs setObject:currentTimestamp forKey:@"last_downloaded_update"];
[prefs setObject:apiUpdateTimestamp forKey:@"api_update_timestamp"];
[prefs synchronize];
// Set the lastDownloadedTimestamp as today
// Set the last
}