可能我的问题看起来很奇怪,但是......(希望有人帮助我)
我从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);
}
有时,在这两种方法之一中,应用程序挂起并控制冻结。
任何人都可以给我一些建议,说明可能存在错误。
我很困惑......
EDITED
我注意到有趣的事情:
下载过程在应用运行时启动。它从服务器下载 Recipes 并将其插入CoreData。如果我点按食谱列表,我会使用appDelegate.managedObjectContext
来获取数据。当想要插入数据时,下载也会使用appDelegate.managedObjectContext
。
这可能包含问题吗?