Объектив- c Non Ar c Объект - PullRequest
       22

Объектив- c Non Ar c Объект

1 голос
/ 06 апреля 2020

Я управляю старым проектом Objective- c, который все еще использует Non Arc, я заметил в Fabric Crashlytics для EXC_BAD_ACCESS KERN_INVALID_ADDRESS cra sh в приложении.

Это трассировка к крару sh, у меня есть эта строка кода:

[view.label setText:[historyArray getStringForVideoArray]];

, которая вызывает эту функцию:

-(NSString*)getStringForVideoArray {
    NSString *str = nil;

    int seconds = 0;

    for (NSObject *video in self) {
        if (!video) {
            continue;
        }
        if ([video isKindOfClass:[VideoItem class]]) {
            VideoItem *tmp = (VideoItem*)video;
            seconds += tmp.seconds;
        }
    }

    if (seconds != 0) {
        int minutes = seconds / 60;
        if (minutes == 0 || minutes == 1) {
            minutes = 1;
            str = [NSString stringWithFormat:@"%d Min.",minutes];
        } else {
            str = [NSString stringWithFormat:@"%d Mins.",minutes];
        }
    } else {
        str = [NSString stringWithFormat:@""];
    }

    return str;
}

Из того, что я заметил из Fabric Crashlytics, крей sh в этой строке:

if ([video isKindOfClass:[VideoItem class]]) {

Единственное, что я могу подумать, что может сделать этот cra sh, это то, что historyArray создано в этом методе:

historyArray = [[NSMutableArray alloc] initWithArray:historyRep.historyArray];

И это определение массива в классе:

@interface HistoryViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    NSMutableArray *historyArray;
}

Есть идеи, что может сделать этот cra sh? Невозможно изменить проект на код AR C, я действительно разочарован тем, что не могу найти эту проблему cra sh.

Edit

Это три способа вставки элементов в массив:

1) При обмене позиции элемента в массиве:

id object = [[[self.historyArray objectAtIndex:firstIndex] retain] autorelease];
[self.historyArray removeObjectAtIndex:firstIndex];
[self.historyArray insertObject:object atIndex:secondIndex];

2) Вставка элемента из другого класса: [self.historyArray insertObject: video atIndex: 0]; Созданный из:

if (self.videoItem)
    [self.videoItem release];
self.videoItem = [[VideoItem alloc] initWithVideoItem:item];

3) Инициируйте массив в первый раз с помощью:

NSArray *myRepository = [[NSUserDefaults standardUserDefaults] arrayForKey:@"kHistory"];
if(myRepository) { 
    for(NSData *data in myRepository) {
        VideoItem *video = (VideoItem*)[NSKeyedUnarchiver unarchiveObjectWithData:data];
        [self.historyArray addObject:video];
    }
}

Есть предложения, что может создать проблему?

1 Ответ

1 голос
/ 06 апреля 2020

Поскольку это изменяемый массив, он может быть очищен во время итерации, что приводит к тому, что cra sh точно в указанной строке (потому что предыдущее условие только для true, поэтому даже висячий указатель может пройти, более того, он не имеет смысла).

Здесь возможно решение

-(NSString*)getStringForVideoArray {
    NSString *str = nil;

    int seconds = 0;

    NSArray *tmp = [NSArray arrayWithArray:self]; // shallow copy - fast
    for (NSObject *video in tmp) {
        if ([video isKindOfClass:[VideoItem class]]) {
            VideoItem *tmp = (VideoItem*)video;
            seconds += tmp.seconds;
        }
    }

    ... // all below with no changes
}
...