سؤال

تعطل التطبيق مع وجود خطأ:

*** 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) الخاصة بقراءة التعليقات التوضيحية في الخلفية، ثم تمرير عمل واجهة المستخدم مرة أخرى إلى سلسلة المحادثات الرئيسية.أتمنى أن يساعدك هذا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top