简体   繁体   English

Objective-c 非弧 Object

[英]Objective-c Non Arc Object

I'm managing an old Objective-c Project that still uses Non Arc , I noticed in Fabric Crashlytics for EXC_BAD_ACCESS KERN_INVALID_ADDRESS crash in the application.我正在管理一个仍然使用Non Arc的旧 Objective-c 项目,我在Fabric Crashlytics中注意到应用程序中的EXC_BAD_ACCESS KERN_INVALID_ADDRESS崩溃。

This is the trace to the crash, I have this code line:这是崩溃的痕迹,我有这个代码行:

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

That call this function:那叫这个function:

-(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;
}

From what I noticed from Fabric Crashlytics , the crash is in this line:根据我从Fabric Crashlytics中注意到的情况,崩溃出现在这一行:

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

The only thing I can think that can make this crash is that historyArray created in this method:我能想到的唯一可以使这个崩溃的是historyArray在这个方法中创建的:

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

And this is the definition of the array in the class:这是class中数组的定义:

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

Any idea what can make this crash?知道什么会导致这次崩溃吗? It's not possible to change the project to ARC code, I'm really frustrated with not find this crash problem.无法将项目更改为 ARC 代码,我真的很沮丧没有找到这个崩溃问题。

Edit编辑

This is the three ways I insert items to the array:这是我将项目插入数组的三种方式:

1) When exchanging the position of an item in the array: 1)交换数组中某项的position时:

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

2) Insert item from another class: [self.historyArray insertObject:video atIndex:0]; 2) 从另一个 class 插入项目:[self.historyArray insertObject:video atIndex:0]; That created from:创建自:

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

3) Init the array in the first time with: 3)第一次初始化数组:

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

Any suggestions what can make the problem?有什么建议会导致问题吗?

As this is mutable array it can be cleaned during iteration that result in crash exactly at the line reported (because previous condition just for true, so even dangling pointer can pass, moreover it is senseless).由于这是一个可变数组,它可以在迭代过程中被清理,从而导致在报告的行发生崩溃(因为先前的条件只是为真,所以即使是悬空指针也可以通过,而且它是毫无意义的)。

Here is possible solution这是可能的解决方案

-(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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM