EXC_BAD_ACCESS与NSDictionary / CFDictionaryRef

时间:2015-05-15 15:30:49

标签: objective-c nsdictionary exc-bad-access

我有以下代码:(很长)

{"where": {"archived_at":{ "neq": null }}}

随机(=不是每次),当控制达到这种情况时,将发生错误(EXC_BAD_ACCESS或EXC_I386_GPFLT),它将分别由//declarations (in the header) : NSDictionary* batteryRawDict; @property (strong, atomic, readonly) NSDictionary* batteryReport; //this dictionary is, obviously, @synthesize'd case PFSKGroupBattery: { //to get more informations or to subscribe for events about power sources, use the IOPowerSources API if (!firstRunDoneForBattery) { batEntry = IOServiceGetMatchingService(masterPort, IOServiceMatching("IOPMPowerSource")); if (batEntry == 0) { _error = PFSKReturnComponentUnavailable; return false; } } CFMutableDictionaryRef batProps = NULL; result = IORegistryEntryCreateCFProperties(batEntry, &batProps, NULL, 0); if (result!=kIOReturnSuccess) { _error = PFSKReturnIOKitCFFailure; _extError = result; return false; } else { batteryRawDict = (__bridge NSDictionary*)batProps; CFRelease(batProps); NSMutableDictionary* temp = [NSMutableDictionary.alloc init]; if (!firstRunDoneForBattery) { //static keys //[temp setObject:[batteryRawDict objectForKey:@"DesignCapacity"] forKey:@"DesignedCapacity"]; [temp setObject:[batteryRawDict objectForKey:@"DesignCycleCount9C"] forKey:@"DesignedCycleCount"]; [temp setObject:[batteryRawDict objectForKey:@"BatterySerialNumber"] forKey:@"Serial"]; [temp setObject:[batteryRawDict objectForKey:@"DeviceName"] forKey:@"Model"]; [temp setObject:[batteryRawDict objectForKey:@"Manufacturer"] forKey:@"Manufacturer"]; unsigned int manufactureDateAsInt = [[batteryRawDict objectForKey:@"ManufactureDate"] intValue]; NSDateComponents* manufactureDateComponents = [[NSDateComponents alloc]init]; manufactureDateComponents.year = (manufactureDateAsInt >> 9) + 1980; manufactureDateComponents.month = (manufactureDateAsInt >> 5) & 0xF; manufactureDateComponents.day = manufactureDateAsInt & 0x1F; [temp setObject:[[NSCalendar currentCalendar] dateFromComponents:manufactureDateComponents] forKey:@"ManufactureDate"]; firstRunDoneForBattery = 1; } [temp setObject:[batteryRawDict objectForKey:@"BatteryInstalled"] forKey:@"isPresent"]; [temp setObject:[batteryRawDict objectForKey:@"FullyCharged"] forKey:@"isFull"]; [temp setObject:[batteryRawDict objectForKey:@"IsCharging"] forKey:@"isCharging"]; [temp setObject:[batteryRawDict objectForKey:@"ExternalConnected"] forKey:@"isACConnected"]; [temp setObject:[batteryRawDict objectForKey:@"Amperage"] forKey:@"Amperage"]; [temp setObject:[batteryRawDict objectForKey:@"CurrentCapacity"] forKey:@"CurrentCapacity"]; [temp setObject:[batteryRawDict objectForKey:@"MaxCapacity"] forKey:@"MaxCapacity"]; [temp setObject:[batteryRawDict objectForKey:@"Voltage"] forKey:@"Voltage"]; [temp setObject:[batteryRawDict objectForKey:@"CycleCount"] forKey:@"CycleCount"]; [temp setObject:@(([[batteryRawDict objectForKey:@"MaxCapacity"] intValue] / [[batteryRawDict objectForKey:@"DesignCapacity"] intValue])*100) forKey:@"Health"]; //percentage [temp setObject:@([[batteryRawDict objectForKey:@"Temperature"] doubleValue] / 100) forKey:@"Temperature"]; /*to be checked*/[temp setObject:@([[batteryRawDict objectForKey:@"Amperage"] doubleValue] / 1000 * [[batteryRawDict objectForKey:@"Voltage"] doubleValue] / 1000) forKey:@"Power"]; NSDateComponents* differenceDate = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:[temp objectForKey:@"ManufactureDate"] toDate:[NSDate date] options:0]; [temp setObject:@([differenceDate day]) forKey:@"Age"]; batteryReport = [temp copy]; NSLog(@"-----------------------awesome debugging code-----------"); } CFRelease(batProps); break; } 上的xCode或@implementation行定位。

有关为何发生这种情况的任何想法? 谢谢!

1 个答案:

答案 0 :(得分:2)

看起来糟糕的内存管理。

在将指针桥接到CFRelease之后,您在batProps上致电NSDictionary。这使batteryRawDict指向垃圾。

我建议你改变这两行:

batteryRawDict = (__bridge NSDictionary*)batProps;
CFRelease(batProps);

为:

batteryRawDict = (__bridge_transfer NSDictionary *)batProps;

如果您使用ARC,那么您就完成了。如果您使用的是MRC,请在适当的位置添加对[batteryRawDict release];的呼叫。

您还会在CGRelease(batProps);声明的末尾再次致电case。这也是一个问题。不要过度发布指针。

也在代码上运行Analyzer。这应该指出这些问题。