2010-08-21 5 views
3

J'implémente un droit CLLocationManager comme décrit dans plusieurs tutoriels. Tout fonctionne bien jusqu'au point où le LocationManager reçoit une deuxième mise à jour. Ensuite, une fuite de mémoire se produit.CLLocationManager - Fuite de mémoire étrange

Instruments me dit, que les objets sont divulgués NSCFTimer, GeneralBlock-16 et NSCFSet

Toutes les idées?

Merci pour toute aide

[Modifier]

Après le démarrage et l'arrêt du repeatingly LocationManager, la mise à jour semblent venir plus vite. Cela me fait penser que le CLLocationManager initialise une nouvelle minuterie chaque fois qu'une mise à jour d'emplacement se produit ... TRÈS étrange ...

Et - donc vous n'avez pas besoin de lire mon commentaire - l'application se bloque après un certain temps

[Modifier]

Ok - Je ne comprends pas est un code ici ...

J'utilise une classe distincte pour le LocationManager, comme décrit ici: 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 

puis, dans la principale classe que j'appelle:

mainFile.h (Exerpt)

#import "locationManager.h" 

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

@end 

mainFile.m (Exerpt)

#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 

Ça me rend un peu fou :)

+0

L'application plante-t-elle, après 100 secondes, à chaque fois?Parce que cela devrait être le cas puisque vous envoyez un message différé à un objet qui n'implémente pas de méthode pour ce message. Il devrait également planter au hasard puisque vous libérez le gestionnaire de position mais vous maintenez toujours une référence à lui. –

+0

@Swissdude a trouvé la solution à ce problème? –

+0

donc, est-ce une véritable fuite de mémoire? du cadre de localisation? ou était-ce dans votre code? –

Répondre

0

Mon conseil est de ne pas être obsédé par des fuites de mémoire ponctuelles que l'iOS lui-même génère. Il le fait dans beaucoup d'endroits et les fuites sont toutes assez inoffensives.

+0

Mais l'application se bloque après un certain temps - donc je suppose, je devrais être concerné;) – Swissdude

+0

Ensuite, vous avez de plus gros problèmes. Post plus de code si vous voulez des conseils. –

+0

Il est très peu probable qu'une petite fuite iOS interne plante votre application. Publiez les journaux de plantage dans une autre question si vous avez besoin d'aide pour cela. – raidfive

0

Essayez de faire un Build and Analyze. Je trouve habituellement des fuites de mémoire et d'autres erreurs non syntaxiques de cette façon.

0

Ah, un problème depuis longtemps mort, je les aime. LocationController est un iVar, pas une propriété, donc lorsque vous le créez dans viewDidLoad, l'assigner à _locationController ne prend pas la propriété.

Vous avez libéré l'objet de manière automatique, la prochaine fois que la boucle d'événements est déclenchée, le pool de libérations automatiques est drainé et libéré. Vous pouvez le corriger en en faisant une propriété retain (qui correspondrait à votre locationManager = nil), ou en vous débarrassant de la version automatique, et en utilisant une version [locationmanager] explicite dans dealloc.