NSMutableArray随机释放对象

时间:2014-04-17 14:25:10

标签: ios nsmutablearray release

使用我的应用程序,用户可以在旅途中使用LocationManager记录驱动器,以进行不同的计算。这些计算在类Calculator中完成。这通常可以正常工作,除非有时显然NSMutableArrays energyArrayenergyOnlyDriveArray会丢失所有存储的值,然后将其写为nil int Core Data。

以下是代码:

DriveView加载

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会告诉位置管理员开始更新位置并调用initDatainitCarData

Calculator.h

@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;

...

Calculator.m

@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个小时的车程。

非常感谢你的帮助!

0 个答案:

没有答案