تم تحور NSArrayM أثناء تعداده
سؤال
تعطل التطبيق مع وجود خطأ:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x21481c10> was mutated while being enumerated.'
يحدث هذا فقط إذا انتقلت إلى عرض الخريطة أثناء تحميل التعليقات التوضيحية.إذا لم ألمس الخريطة، فلن يحدث أي خطأ.
- (void) startloading
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
[self loadPList];
});
}
الكود الخاص بي هو:
- (void) loadPList
{
@autoreleasepool {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:@"test.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSMutableArray * annotationsToRemove = [ mapView.annotations mutableCopy ] ;
[ annotationsToRemove removeObject:mapView.userLocation ] ;
[ mapView removeAnnotations:annotationsToRemove ] ;
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"blackKey"])
{
NSArray *ann = [dict objectForKey:@"Black"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:@"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:@"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:@"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:@"Icon"];
[mapView addAnnotation:myAnnotation]; // SIGNAL SIGABRT
[annotations addObject:myAnnotation];
}
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"blueyellowKey"])
{
NSArray *ann = [dict objectForKey:@"BlueYellow"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:@"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:@"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:@"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:@"Icon"];
[mapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
}
}
}
}
المحلول
أعتقد أنه يجب عليك تغيير الخاص بك loadPlist
طريقة لهذا، ثم اتصل فقط [self loadPlist]
لاستدعائه:
- (void) loadPList
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:@"test.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
//ALL THIS CODE FROM HERE ON OUT IS NOT THREAD SAFE! YOU ARE ACCESSING THE UI AND MUST PERFORM IT ON THE MAIN THREAD!
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSMutableArray * annotationsToRemove = [ mapView.annotations mutableCopy ] ;
[ annotationsToRemove removeObject:mapView.userLocation ] ;
[ mapView removeAnnotations:annotationsToRemove ] ;
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"blackKey"])
{
NSArray *ann = [dict objectForKey:@"Black"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:@"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:@"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:@"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:@"Icon"];
[mapView addAnnotation:myAnnotation]; // SIGNAL SIGABRT
[annotations addObject:myAnnotation];
}
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"blueyellowKey"])
{
NSArray *ann = [dict objectForKey:@"BlueYellow"];
for(int i = 0; i < [ann count]; i++)
{
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:@"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:@","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:@"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:@"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:@"Icon"];
[mapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
}
}
}
});
}
يؤدي هذا إلى تنفيذ عملية الإدخال والإخراج (IO) الخاصة بقراءة التعليقات التوضيحية في الخلفية، ثم تمرير عمل واجهة المستخدم مرة أخرى إلى سلسلة المحادثات الرئيسية.أتمنى أن يساعدك هذا!
لا تنتمي إلى StackOverflow