Ошибка сегментации: 11, когда объект возвращает NSArray - PullRequest
1 голос
/ 19 декабря 2011

У меня есть класс, который входит в систему на сервере и получает некоторые данные.Данные помещаются в NSMutableArray, преобразуются в NSArray и возвращаются.Код называется так:

1. NSLog(@"Filling tempoArray");
2. NSArray *tempoArray = [myLogin getRoster:[self employmentnumber] online:YES];
3. NSLog(@"Setting calendarItems with tempoArray");

В объекте 'myLogin' массив создается так:

4. NSMutableArray *calendarItems = [[NSMutableArray alloc]init];

5. Filling the array...

6. NSArray *tempoArray2 = [[NSArray alloc]initWithArray:calendarItems]; //Converting from mutabe to a normal array
7. NSLog(@"tempoArray2 filled with calendarItems. tempoArray2.count:%d", tempoArray2.count);
8. return tempoArray2;

NSLog в строках 1 и 7 записывается вконсоль, но строка 3 никогда не видна, поэтому она вылетает в строке 2.

Интересно, скоро ли будет выпущен tempoArray2?И если так, как я могу избежать этого с ARC?

Ошибка появляется только тогда, когда я загружаю приложение из AppStore, я никогда не видел никаких проблем с этим в любом сценарии отладки.Как это может быть?Вот почему я использую журнал консоли, чтобы точно определить ошибку.Символика в XCode работает не очень хорошо.

РЕДАКТИРОВАТЬ Вот «строка 5»

Это анализ веб-страницы.

    NSString *heleTeksten = [[NSString alloc] initWithData:self.rosterurlmutabledata encoding:NSISOLatin1StringEncoding];
    //NSLog(@"heleteksten%@", heleTeksten);

    NSArray  *lines = [heleTeksten componentsSeparatedByString:@"\n"];
    NSString *searchFor = @"<span class='param";    
    NSString *param1date;
    NSString *param2duty;
    NSString *param3activity;
    NSString *param5checkIn;
    NSString *param6from;
    NSString *param7std;
    NSString *param8sta;
    NSString *param9to;

    int firstPlace;
    NSRange firstRange, secondRange, thirdRange;

    for (__strong NSString* line in lines)
    {
        firstRange = [line rangeOfString:searchFor];
        if (firstRange.location != NSNotFound)
        {
            thirdRange = [line rangeOfString:@"style=\"Padding-top"];
            if (thirdRange.location == NSNotFound) {
                //NSLog(@"New line: %@", line);

                if ([line rangeOfString:@"<B>"].location != NSNotFound) {
                    line = [self removeBfromLine:line];

                }
                if ([line rangeOfString:@";"].location != NSNotFound) {
                    line = [line stringByReplacingOccurrencesOfString:@";" withString:@""];
                }
                secondRange = [line rangeOfString:@"style='color: '>"];

                if (secondRange.location != NSNotFound) {
                    firstPlace = secondRange.location + 16;
                }
                NSString *partOfLine;
                partOfLine = [line substringFromIndex:firstPlace];

                secondRange = [partOfLine rangeOfString:@"<"];

                if (secondRange.location != NSNotFound) 
                {
                    //NSLog(@"partOfLine = [partOfLine substringToIndex:secondRange.location] Line:%@", line);
                    partOfLine = [partOfLine substringToIndex:secondRange.location];
                }
                else {
                    //TODO: Endre errorLog her til myErrorReport:
                    //                        [self errorLog:[@"'<' not found in partofline. Line: " stringByAppendingString:line]];
                }

                partOfLine = [partOfLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

                if ([partOfLine length]>0 || [line rangeOfString:@"param11"].location != NSNotFound)
                {                   
                    if ([line rangeOfString:@"'param1'"].location != NSNotFound ) 
                        // Date-line
                    {
                        param1date = nil;
                        param1date = [NSString stringWithString:partOfLine];
                    }
                    else if ([line rangeOfString:@"param7"].location != NSNotFound)
                        // STD-line
                    {
                        param7std = [NSString stringWithString:partOfLine];
                    }
                    else if ([line rangeOfString:@"param8"].location != NSNotFound)
                        // STA-line
                    {
                        param8sta = [NSString stringWithString:partOfLine];
                    }
                    else if ([line rangeOfString:@"param5"].location != NSNotFound)
                        // CheckIn-line
                    {
                        param5checkIn = [NSString stringWithString:partOfLine];
                    }
                    else if ([line rangeOfString:@"param6"].location != NSNotFound)
                        // Orig-line
                    {
                        param6from = [NSString stringWithString:partOfLine];
                    }

                    else if ([line rangeOfString:@"param9"].location != NSNotFound)
                        // Dest-line
                    {
                        param9to = [NSString stringWithString:partOfLine];
                    }

                    else if ([line rangeOfString:@"param2"].location != NSNotFound)
                        // Duty-line
                    {
                        if ([userdefaults boolForKey:@"inklDutyCodes"])
                        {
                            param2duty = [NSString stringWithString:partOfLine];
                        }

                    }

                    else if ([line rangeOfString:@"param3"].location != NSNotFound)
                        // FlightNo-line
                    {
                        param3activity = [NSString stringWithString:partOfLine];
                    }
                    else if ([line rangeOfString:@"param11"].location != NSNotFound)
                        // Last line. Save calendarItem
                    {
                        calendarItem *newCalendarItem = [[calendarItem alloc]init];
                        //                        currentDate = [self makeNormalDate:partOfLine forAirport:param6from];

                        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];

                        if (param7std == nil)   // = whole day event
                        {
                            [newCalendarItem setWholeDay:YES];
                            [newCalendarItem setSubject:param3activity];
                            if (param6from == nil)
                            {
                                [newCalendarItem setStartTime:[self makeNormalDate:param1date forAirport:@"OSL"]];
                            }
                            else
                            {
                                [newCalendarItem setStartTime:[self makeNormalDate:param1date forAirport:param6from]];
                            }

                            [newCalendarItem setEndTime:newCalendarItem.startTime];
                        }
                        else 
                        {
                            if (param2duty != nil)
                            {
                                [newCalendarItem setDuty:[NSString stringWithString:param2duty]];
                            }
                            else
                            {
                                [newCalendarItem setDuty:[NSString stringWithString:[NSString string]]];
                            }
                            [newCalendarItem setWholeDay:NO];

                            if (param6from != nil)
                                [newCalendarItem setOrig:param6from];
                            else
                                [newCalendarItem setOrig:[NSString string]];

                            if (param9to != nil)
                                [newCalendarItem setDest:param9to];
                            else
                                [newCalendarItem setOrig:[NSString string]];

                            if (param3activity != nil) 
                            {
                                if ([param3activity integerValue])  //Sjekker at det her kun er tall 
                                {
                                    [newCalendarItem setSubject:[@"SK" stringByAppendingString:param3activity]];

                                }
                                else 
                                {
                                    [newCalendarItem setSubject:param3activity];
                                }
                            }
                            else
                            {
                                [newCalendarItem setSubject:[NSString string]];
                            }

                            if (param7std != nil)
                            {
                                if ([param7std length] == 4) 
                                {
                                    NSString *dateAndTimeString = [param1date stringByAppendingString:param7std];
                                    NSLocale * enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 
                                    [dateFormatter setLocale:enUSPOSIXLocale];
                                    NSTimeZone *thisTimeZone;
                                    if (param6from != nil)
                                    {
                                        thisTimeZone = [self timeZoneForAirport:param6from];
                                    }
                                    if (thisTimeZone == nil)
                                    {
                                        thisTimeZone = [NSTimeZone timeZoneWithName:@"Europe/Oslo"];
                                    }
                                    [dateFormatter setTimeZone:thisTimeZone];
                                    [dateFormatter setDateFormat:@"ddMMMyyHHmm"];

                                    [newCalendarItem setStartTime:[dateFormatter dateFromString:dateAndTimeString]];

                                    if (param5checkIn != nil)
                                    {
                                        calendarItem *checkInCalendarItem = [[calendarItem alloc]init];
                                        NSString *checkinTimeString = [param1date stringByAppendingString:param5checkIn];

                                        [checkInCalendarItem setWholeDay:NO];
                                        [checkInCalendarItem setStartTime:[dateFormatter dateFromString:checkinTimeString]];
                                        [checkInCalendarItem setEndTime:[checkInCalendarItem startTime]];
                                        [checkInCalendarItem setSubject:@"Check In"];
                                        [[self calendarItems] addObject:checkInCalendarItem];
                                        checkInCalendarItem = nil;
                                    }

                                }
                                else 
                                {
                                    [mydelegate myErrorLogFromClass:self andMethod:@"getRoster:Online:" withFreeText:[NSString stringWithFormat:@"STD ikke 4 lang. Line: %@", line] andListofIvars:nil];
                                }
                            }
                            else
                            {
                                [mydelegate myErrorLogFromClass:self andMethod:@"getRoster:Online:" withFreeText:[NSString stringWithFormat:@"STD er nil. Line: %@", line] andListofIvars:nil];
                            }

                            if (param8sta != nil)
                            {
                                if ([param8sta length] == 4) {

                                    NSString *dateAndTimeString = [param1date stringByAppendingString:param8sta];
                                    NSLocale * enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 
                                    [dateFormatter setLocale:enUSPOSIXLocale];
                                    NSTimeZone *thisTimeZone2;
                                    if (param9to != nil)
                                    {
                                        thisTimeZone2 = [self timeZoneForAirport:param9to];
                                    }
                                    else if (param6from != nil) //Kan skje ved stby
                                    {
                                        thisTimeZone2 = [self timeZoneForAirport:param6from];
                                        NSLog(@"thisTimeZone2 satt til param6From for param9To er nil. Dato:%@", dateAndTimeString);
                                    }
                                    if (thisTimeZone2 == nil)
                                    {
                                        thisTimeZone2 = [NSTimeZone timeZoneWithName:@"Europe/Oslo"];
                                        NSLog(@"thisTimeZone2 satt til OSL. param9to er nil.");
                                    }
                                    [dateFormatter setTimeZone:thisTimeZone2];
                                    [dateFormatter setDateFormat:@"ddMMMyyHHmm"];
                                    NSDate *tempoDate = [dateFormatter dateFromString:dateAndTimeString];

                                    if([tempoDate compare:newCalendarItem.startTime] == NSOrderedAscending)
                                    {
                                        tempoDate = [NSDate dateWithTimeInterval:86400 sinceDate:tempoDate];
                                    }
                                    [newCalendarItem setEndTime:tempoDate];
                                }
                                else 
                                {
                                    [mydelegate myErrorLogFromClass:self andMethod:@"getroster:online:" withFreeText:[NSString stringWithFormat:@"STA-felt ikke 4 lang. Line: %@",line] andListofIvars:nil];
                                }
                            }
                            else
                            {
                                    [mydelegate myErrorLogFromClass:self andMethod:@"getroster:online:" withFreeText:[NSString stringWithFormat:@"STA-felt er nil. Line: %@",line] andListofIvars:nil];
                            }
                        }

                        if (param3activity != nil)
                        {
                            if ([param3activity rangeOfString:@"GO"].location == NSNotFound && 
                                [param3activity rangeOfString:@"VO"].location == NSNotFound)
                            {
                                if ([self itemOkAccordingToPreferences:newCalendarItem])
                                {
                                    [[self calendarItems] addObject:newCalendarItem];
                                }                                   
                            }
                        }

                        param2duty = nil;
                        param3activity = nil;
                        param6from = nil;
                        param7std = nil;
                        param8sta =nil;
                        param9to = nil;
                        param5checkIn = nil;
                    }               
                } //End of if ([partOfLine length]>0)               
            }
        }
    } // End of for (NSString* line in lines)


    NSLog(@"Ferdig med å tygge dataene. Funnet %d calendarItems", [[self calendarItems] count]);

    NSArray *tempoArray2 = [[NSArray alloc]initWithArray:[self calendarItems]];

    NSLog(@"tempoArray2 fyllt med calendarItems. tempoArray2.count:%d", tempoArray2.count);
    return tempoArray2;

1 Ответ

1 голос
/ 19 декабря 2011

Если это действительно весь код, то я могу подумать о некоторых сценариях, в которых это может произойти сбой.Во-первых, если у вас есть несколько потоков, очень вероятно, что вы зависаете в другом потоке.

Если это единственный поток, то я подозреваю, что где-то в «строке 5» вы создаете данные, которые неправильно управляются памятью,В ARC это требует либо того, что вы вызываете не-ARC-код, либо в какой-то момент вы выполняете __bridge приведения, либо вы неправильно управляете malloc памятью (возможно, в dealloc чего-то, созданного в«строка 5»).

В строке 2 tempoArray может быть немедленно освобождено, если оно не используется после строки 2. Если оно используется после строки 2, то практически невозможно представить, что оно будет освобожденослишком рано, если вы не сделали что-то действительно странное (например, тип возврата getRoster... be __unsafe_unretained NSArray*).

Другая возможность - это если вы разбиваете свой собственный стек.Это может произойти, если вы разместите массивы или строки C в своем стеке, а затем запишете их конец.Скорее всего, это будет в «строке 5».

Тот факт, что вы видите это в поле, предполагает, что это может быть связано с оптимизацией.Обязательно выполните тестирование в режиме Release.

Ваши соглашения об именах неверны, что может создать проблемы в коде ARC, хотя я сомневаюсь, что это реальная проблема.Ведущий get в getRoster:online: должен быть удален.Ведущий get указывает, что метод возвращает свой результат по ссылке.Тем не менее, я не верю, что ARC применяет какое-либо специальное управление памятью в этом случае, поэтому я не думаю, что это вызывает ваш сбой.См. Руководство по KVC для получения полной информации о правильном присвоении имен, чтобы ARC знал, что вы делаете.

Тот факт, что символика работает не очень хорошо, говорит о том, что вы, возможно, смотрите на другоеФайл dSYM, чем код, который вы отправили.Убедитесь, что вы всегда сохраняете dSYM и двоичный файл пакета, который вы отправляете в магазин приложений.Xcode использует центр внимания, чтобы найти соответствующий dSYM.

...