Objective-c 非圆弧对象
Objective-c Non Arc Object
我正在管理一个仍在使用 Non Arc
的旧 Objective-c 项目,我在 Fabric Crashlytics
中注意到 EXC_BAD_ACCESS KERN_INVALID_ADDRESS
应用程序崩溃。
这是崩溃的痕迹,我有这个代码行:
[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
中注意到的情况,崩溃发生在这一行:
if ([video isKindOfClass:[VideoItem class]]) {
我认为唯一会导致崩溃的是 historyArray
在这个方法中创建:
historyArray = [[NSMutableArray alloc] initWithArray:historyRep.historyArray];
这是class中数组的定义:
@interface HistoryViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *historyArray;
}
知道是什么导致了这次崩溃吗?无法将项目更改为 ARC 代码,找不到这个崩溃问题,我真的很沮丧。
编辑
这是我向数组插入项的三种方式:
1) 交换数组中某一项的位置时:
id object = [[[self.historyArray objectAtIndex:firstIndex] retain] autorelease];
[self.historyArray removeObjectAtIndex:firstIndex];
[self.historyArray insertObject:object atIndex:secondIndex];
2) 从另一个 class 插入项目:
[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];
}
}
有什么建议可以解决问题吗?
由于这是一个可变数组,它可以在迭代过程中被清除,导致恰好在报告的行发生崩溃(因为之前的条件只是为真,所以即使悬空指针也可以通过,而且它是无意义的)。
这是可能的解决方案
-(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
}
我正在管理一个仍在使用 Non Arc
的旧 Objective-c 项目,我在 Fabric Crashlytics
中注意到 EXC_BAD_ACCESS KERN_INVALID_ADDRESS
应用程序崩溃。
这是崩溃的痕迹,我有这个代码行:
[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
中注意到的情况,崩溃发生在这一行:
if ([video isKindOfClass:[VideoItem class]]) {
我认为唯一会导致崩溃的是 historyArray
在这个方法中创建:
historyArray = [[NSMutableArray alloc] initWithArray:historyRep.historyArray];
这是class中数组的定义:
@interface HistoryViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *historyArray;
}
知道是什么导致了这次崩溃吗?无法将项目更改为 ARC 代码,找不到这个崩溃问题,我真的很沮丧。
编辑
这是我向数组插入项的三种方式:
1) 交换数组中某一项的位置时:
id object = [[[self.historyArray objectAtIndex:firstIndex] retain] autorelease];
[self.historyArray removeObjectAtIndex:firstIndex];
[self.historyArray insertObject:object atIndex:secondIndex];
2) 从另一个 class 插入项目: [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];
}
}
有什么建议可以解决问题吗?
由于这是一个可变数组,它可以在迭代过程中被清除,导致恰好在报告的行发生崩溃(因为之前的条件只是为真,所以即使悬空指针也可以通过,而且它是无意义的)。
这是可能的解决方案
-(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
}