CLLocationManager - странная утечка памяти - PullRequest
3 голосов
/ 21 августа 2010

Я реализую CLLocationManager правильно, как описано в нескольких руководствах.

Все отлично работает до того момента, когда LocationManager получает второе обновление. Затем происходит утечка памяти.

Приборы сообщают мне, что утечка объектов - NSCFTimer, GeneralBlock-16 и NSCFSet

Есть идеи?

Спасибо за любую помощь

[редактировать]

После многократного запуска и остановки locationManager обновленные версии появляются быстрее. Это заставляет меня думать, что CLLocationManager инициализирует новый таймер каждый раз, когда происходит обновление местоположения ... ОЧЕНЬ странно ...

И - так что вам не нужно читать мой комментарий - приложение через некоторое время вылетает

[Изменить]

Хорошо, я не понимаю, вот какой-то код ...

Я использую отдельный класс для locationManager, как описано здесь: http://www.vellios.com/2010/08/16/core-location-gps-tutorial/

locationManager.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@protocol locationManagerDelegate 

@required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
@end

@interface locationManager : NSObject <CLLocationManagerDelegate>{
    CLLocationManager *myLocationManager;
    id delegate;
    CLLocation *bestEffortAtLocation;
    BOOL    outOfRange;
}

@property (nonatomic, retain) CLLocationManager *myLocationManager;  
@property (nonatomic, retain) CLLocation *bestEffortAtLocation;
@property (nonatomic, assign) id  delegate;
@property (nonatomic, assign) BOOL  outOfRange;

@end

locationManager.m

#import "locationManager.h"

@implementation locationManager

@synthesize myLocationManager;
@synthesize delegate;
@synthesize bestEffortAtLocation;
@synthesize outOfRange;

- (id) init {
    self = [super init];
    NSLog(@"initializing CLLocationManager");
    if (self != nil) {
        outOfRange = NO;

        self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
        self.myLocationManager.delegate = self;

        self.myLocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;

        [self performSelector:@selector(stopUpdatingLocation:) withObject:@"Timed Out" afterDelay:100.0];
    }else{
        NSLog(@"Location Manager could not be initialized");
    }
    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{

    if(outOfRange == NO){

        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];

        NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
        if (locationAge > 5.0) return;
        // test that the horizontal accuracy does not indicate an invalid measurement
        if (newLocation.horizontalAccuracy < 0) return;

        [self.delegate locationUpdate:newLocation];
    }else{
        [self.myLocationManager stopUpdatingLocation];
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"error!!!!");
    [self.myLocationManager stopUpdatingLocation];
    [self.delegate locationError:error];
}

- (void)dealloc {
    [myLocationManager release];
    [bestEffortAtLocation release];
    [super dealloc];
}

@end

тогда в основном классе я звоню:

mainFile.h (exerpt)

#import "locationManager.h"

@interface mainFile : UIViewController  <locationManagerDelegate , UIAlertViewDelegate>{
    locationManager *locationController;
    CLLocation      *myLocation;
}

@end

mainFile.m (выдержка)

#import "locationManager.h"

@implementation mainFile

@synthesize locationController;
@synthesize myLocation;

- (void)locationError:(NSError *)error{
// Do alert-Stuff
}

- (void)locationUpdate:(CLLocation *)location {
// Do location-Stuff
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    locationController = [[[locationManager alloc] init] autorelease];

    locationController.delegate = self;
    [locationController.myLocationManager startUpdatingLocation];
}

- (void)dealloc {
    self.locationController = nil;
    [locationController release];
}

@end

Это сводит меня с ума:)

Ответы [ 3 ]

0 голосов
/ 21 августа 2010

Попробуйте сделать Build and Analyze.Обычно я нахожу утечки памяти и другие несинтаксические ошибки таким образом.

0 голосов
/ 22 октября 2013

Ах, давно мертвая проблема, я люблю их.

locationController - это iVar, а не свойство, поэтому при его создании в viewDidLoad его присвоение _locationController не вступает во владение.

Вы автоматически освободили объект, поэтому в следующий раз во время цикла событий пул авто-релизов будет очищен и освобожден.

Вы можете исправить это, сделав его сохраняющим свойством (которое будет соответствовать вашему locationManager = nil), или избавившись от авто-релиза, и используя явный [releaseManager release] в dealloc.

0 голосов
/ 21 августа 2010

Мой совет - не зацикливаться на разовых утечках памяти, которые генерирует сама iOS. Это происходит во многих местах, и все утечки практически безвредны.

...