使用我的应用程序,用户可以在旅途中使用LocationManager记录驱动器,以进行不同的计算。这些计算在类Calculator
中完成。这通常可以正常工作,除非有时显然NSMutableArrays energyArray
和energyOnlyDriveArray
会丢失所有存储的值,然后将其写为nil int Core Data。
以下是代码:
DriveView.h
@interface DriveView : UIScrollView <ADBannerViewDelegate,CLLocationManagerDelegate,CalculatorDelegate>
{
Calculator *calculator;
}
@property (nonatomic, strong) Calculator *calculator;
DriveView.m
@implementation DriveView
@synthesize calculator = _calculator;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_calculator = [[Calculator alloc]init];
_calculator.delegate = self;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[_calculator locationManagerDidUpdateLocations:locations];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[_calculator locationManagerDidFailWithError:error];
}
当用户开始录制驱动器时,DriveView会告诉位置管理员开始更新位置并调用initData
和initCarData
。
@interface Calculator : NSObject {
@private
NSMutableArray *energyArray;
NSMutableArray *energyOnlyDriveArray;
}
@property (strong, nonatomic) id <CalculatorDelegate> delegate;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) dispatch_queue_t queue;
@property (nonatomic, strong) NSMutableArray *alt_filtered;
@property (nonatomic, strong) NSMutableArray *energyArray;
@property (nonatomic, strong) NSMutableArray *energyOnlyDriveArray;
@property (nonatomic, strong) NSMutableDictionary *powerVectorDict;
@property (nonatomic, strong) NSMutableArray *carSpecificData;
- (void)initData;
- (void)initCarData;
...
@implementation Calculator
@synthesize managedObjectContext = __managedObjectContext;
@synthesize energyArray = _energyArray;
@synthesize energyOnlyDriveArray = _energyOnlyDriveArray;
- (id)init
{
if (self = [super init])
{
_queue = dispatch_queue_create(NULL, NULL);
}
return self;
}
- (void)initData
{
self.managedObjectContext = [kDelegate managedObjectContext];
}
- (void)initCarData
{
_energyArray = [[NSMutableArray alloc]init]; //stores the energy values
_energyOnlyDriveArray = [[NSMutableArray alloc]init]; //stores the energy values
_carSpecificData = [[NSMutableArray alloc]init];
_alt_filtered = [[NSMutableArray alloc]init];
for (int i = 0; i < [[[Cars manager]carsList] count]; i++) {
[_energyArray addObject:[NSNumber numberWithFloat:0.0f]];
[_energyOnlyDriveArray addObject:[NSNumber numberWithFloat:0.0f]];
[_carSpecificData addObject:[NSDictionary new]];
}
....
}
- (void)locationManagerDidUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = [locations lastObject];
if ((newLocation.horizontalAccuracy > 0) && (newLocation.verticalAccuracy > 0) && (newLocation.horizontalAccuracy < 100) && (newLocation.verticalAccuracy < 100))
{
--> Some code and then `launchAlgorithm:`
}
}
- (void)launchAlgorithm:(Drive*)drive
{
UIApplication* app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an // expiration handler in case the task runs long.
UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
bgTask = [app beginBackgroundTaskWithExpirationHandler: ^{
[app endBackgroundTask:bgTask];
}];
dispatch_async(_queue, ^{
@autoreleasepool {
for (int i = 0; i < [[[Cars manager]carsList] count]; i++) {
[self processAlgorithmResults:[Algorithm that calculation and returns NSDictionary]];
}
if (bgTask != UIBackgroundTaskInvalid) {
dispatch_async(_queue, ^{
[app endBackgroundTask:bgTask];
});
}
}
});
- (void)processAlgorithmResults:(NSMutableDictionary *)driverProfile
{
// write energy into array
float energyValue = [[_energyArray objectAtIndex:i]floatValue] + [[driverProfile objectForKey:@"EVerbrauch"] floatValue];
[_energyArray replaceObjectAtIndex:i withObject:[NSNumber numberWithFloat:energyValue]];
float energyOnlyDriveValue = [[_energyOnlyDriveArray objectAtIndex:i]floatValue] + [[driverProfile objectForKey:@"EVerbrauchOnlyDrive"] floatValue];
[_energyOnlyDriveArray replaceObjectAtIndex:i withObject:[NSNumber numberWithFloat:energyOnlyDriveValue]];
// set power value
NSMutableArray *powerValueArray = [NSMutableArray arrayWithArray:[_powerVectorDict objectForKey:[NSNumber numberWithInteger:i]]];
[powerValueArray addObject:[[driverProfile objectForKey:@"P"]valueForKey:@"Pel_drive"]];
[_powerVectorDict setObject:powerValueArray forKey:[NSNumber numberWithInteger:i]];
}
AFTER THE DRIVE IS DONE EVERYTHING IS SAVED LIKE THIS:
- (void)saveHistory
{
for (int i = 0; i < [[[Cars manager]carsList] count]; i++) {
// power array of the car
NSMutableArray *powerArray = [_powerVectorDict objectForKey:[NSNumber numberWithInt:i]];
History *history = (History *)[NSEntityDescription insertNewObjectForEntityForName:@"History" inManagedObjectContext:self.managedObjectContext];
history.driveID = [[Settings manager]lastDriveID];
history.distance = [NSNumber numberWithFloat:_totalDistance];
history.vMax = [NSNumber numberWithFloat:_maxSpeed];
history.driveDate = firstTime;
history.sentToServer = [NSNumber numberWithBool:NO];
history.vMean = [NSNumber numberWithFloat:_avgSpeed];
history.energy = [NSNumber numberWithFloat:[[_energyArray objectAtIndex:i]floatValue]];
history.energy_onlyDrive = [NSNumber numberWithFloat:[[_energyOnlyDriveArray objectAtIndex:i]floatValue]];
history.car = [[[[Cars manager]carsList] objectAtIndex:i] objectForKey:@"name"];
history.carID = [NSNumber numberWithInt:i];
history.area = [[[[Cars manager]carsList] objectAtIndex:i] objectForKey:@"area"];
history.cw = [[[[Cars manager]carsList] objectAtIndex:i] objectForKey:@"cw"];
history.weight = [[[[Cars manager]carsList] objectAtIndex:i] objectForKey:@"weight"];
history.driveDuration = [NSNumber numberWithFloat:[lastTime timeIntervalSinceDate:firstTime]];
history.temperature = [[Settings manager]localTemperature];
history.temperatureSystem = [[Settings manager]temperatureSystem];
history.precision = [NSNumber numberWithFloat:(((float)_totalSignals-(float)_badSignals))/(float)_totalSignals];
history.includeInProfile = [NSNumber numberWithBool:YES];
history.maxPower = [NSNumber numberWithFloat:[[powerArray objectAtIndex:index]floatValue]];
history.lastSentChunk = [NSNumber numberWithFloat:0];
}
if (self.managedObjectContext != nil)
{
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(@"error: %@",error.description);
NSLog(@"error: %@",error);
}
}
}
现在,当我检索数据时,history.energy和history.energy_onlyDrive的值将返回nil值。
该应用程序也可以在后台运行,并将在那里进行所有计算。 我希望有人可以帮助我。我真的不明白为什么数组被清除似乎是随机的,因为有时它会发生,有时它不会。计算的时间长短也无关紧要。我做了3分钟的车程和3个小时的车程。
非常感谢你的帮助!