可能是我的问题看起来很奇怪,但是......(希望有人帮助我)
有两种方法可以从 FTP 加载一些数据。有时应用程序挂在这些方法上。
- 检查互联网连接。
如果互联网可用:
@interface Download : NSObject { NSOperationQueue *operationQueue; } ... if (!operationQueue) { operationQueue = [NSOperationQueue new]; } NSInvocationOperation *operation1; operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadIngredientsFromJSON) object:nil]; [operationQueue addOperation:operation1]; NSInvocationOperation *operation2; operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadRecipesFromJSON) object:nil]; [operation2 addDependency:operation1]; [operationQueue addOperation:operation2]; [operationQueue addObserver:self forKeyPath:@"operations" options:0 context:NULL];
方法loadIngredientsFromJSON & loadRecipesFromJSON
-(void) loadIngredientsFromJSON { NSInteger countInBase = [self dataCountInEntity:@"Ingredients"]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ftp://...Ingredients.json"]]; NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSError *error = nil; if (!responseData) { return; } NSDictionary *ingredientsDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; if (!ingredientsDictionary) { return; } //NSLog(@"%@", [ingredientsDictionary description]); NSArray *keys = [ingredientsDictionary allKeys]; if (!countInBase && [ingredientsDictionary count]>0) { AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; for (int i=0; i<[ingredientsDictionary count]; i++) { id aKey = [keys objectAtIndex:i]; NSArray *ingrData = [ingredientsDictionary objectForKey:[NSString stringWithFormat:@"%@", aKey]]; NSArray *tmpArray = [NSArray arrayWithObjects:aKey, [ingrData objectAtIndex:0], [ingrData objectAtIndex:1], nil]; Ingredients *ingredient = [NSEntityDescription insertNewObjectForEntityForName:@"Ingredients" inManagedObjectContext:appDelegate.managedObjectContext]; ingredient.code = [NSNumber numberWithInteger:[[tmpArray objectAtIndex:0] integerValue]]; ingredient.name = [tmpArray objectAtIndex:1]; ingredient.units = [tmpArray objectAtIndex:2]; ingredient.type = [NSNumber numberWithInt:1]; [appDelegate.managedObjectContext save:nil]; } } }
...
- (void) loadRecipesFromJSON
{
NSInteger missedCount = 0;
NSInteger recipeCode = 0;
NSString *recipesPath = @"ftp://...";
do {
recipeCode ++;
NSString *recipeFileName = [NSString stringWithFormat:@"recipes/%05d.json", recipeCode];
NSString *recipeFileFullPath = [recipesPath stringByAppendingString:recipeFileName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeFileFullPath]];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError *error = nil;
if (!responseData) {
missedCount ++;
continue;
}
NSDictionary *recipeDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
if (!recipeDictionary) {
missedCount ++;
continue;
}
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSInteger recipeCount = [self isDataExistInEntity:@"Recipes" withCode:[[recipeDictionary objectForKey:@"recipeCode"] integerValue]];
if (recipeCount == 0) {
Recipes *recipe = [NSEntityDescription insertNewObjectForEntityForName:@"Recipes" inManagedObjectContext:appDelegate.managedObjectContext];
recipe.code = [recipeDictionary objectForKey:@"recipeCode"];
recipe.dateUpdated = [recipeDictionary objectForKey:@"dateEdited"];
recipe.inCategory = [recipeDictionary objectForKey:@"inCategory"];
recipe.name = [recipeDictionary objectForKey:@"recipe"];
recipe.difficulty = [recipeDictionary objectForKey:@"difficulty"];
recipe.personCount = [recipeDictionary objectForKey:@"personCount"];
recipe.prepHour = [recipeDictionary objectForKey:@"prepHour"];
recipe.prepMin = [recipeDictionary objectForKey:@"prepMin"];
int seconds = ([recipe.prepMin intValue]*60)+([recipe.prepHour intValue] * 60 * 60);
recipe.prepTime = [NSNumber numberWithInt: seconds];
recipe.isPaid = [recipeDictionary objectForKey:@"isPaid"];
recipe.comment = [recipeDictionary objectForKey:@"comments"];
NSDictionary *ingredients = [recipeDictionary objectForKey:@"ingredients"];
NSArray *keys = [ingredients allKeys];
if ([keys count] > 0) {
for (int i=0; i<[keys count]; i++) {
Join *join = [NSEntityDescription insertNewObjectForEntityForName:@"Join" inManagedObjectContext:appDelegate.managedObjectContext];
join.recipeCode = [recipeDictionary objectForKey:@"recipeCode"];
id aKey = [keys objectAtIndex:i];
join.ingredientCode = [NSNumber numberWithInteger:[aKey integerValue]];
NSString *str = [ingredients objectForKey:aKey];
double num = [str doubleValue];
join.count = [NSNumber numberWithDouble:num];
join.inCart = [NSNumber numberWithInt:0];
}
}
NSDictionary *prepStages = [recipeDictionary objectForKey:@"prepStage"];
keys = [prepStages allKeys];
if ([keys count] > 0) {
for (int i=0; i<[keys count]; i++) {
PrepStages *prepStage = [NSEntityDescription insertNewObjectForEntityForName:@"PrepStages" inManagedObjectContext:appDelegate.managedObjectContext];
prepStage.recipeCode = [recipeDictionary objectForKey:@"recipeCode"];
id aKey = [keys objectAtIndex:i];
prepStage.order = [NSNumber numberWithInteger:[aKey integerValue]];
prepStage.descriptions = [prepStages objectForKey:aKey];
//загрузка картинки
NSString *recipeImageName = [NSString stringWithFormat:@"recipeImages/%05d-%@.jpg", recipeCode, [NSNumber numberWithInteger:[aKey integerValue]]];
NSString *recipeImageFullPath = [recipesPath stringByAppendingString:recipeImageName];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeImageFullPath]];
if (request) {
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (responseData) {
UIImage *image = [UIImage imageWithData:responseData];
prepStage.image = image;
}
}
}
}
[appDelegate.managedObjectContext save:nil];
}
else {
missedCount ++;
continue;
}
} while (missedCount < 10);
}
有时在这两种方法之一中,应用程序挂起和控制冻结。
谁能给我一些建议,哪一行可能有错误。
我糊涂了...
已编辑
我注意到有趣的事情:
下载过程在应用程序运行时开始。它从服务器下载食谱并将它们插入到 CoreData。如果我点击查看我用来获取数据的食谱列表。当它想要插入数据时,appDelegate.managedObjectContext
Download 也会使用。appDelegate.managedObjectContext
这可以包含问题吗?