3

いくつかのチュートリアルで説明されているように、CLLocationManager を正しく実装しています。

LocationManager が 2 番目の更新を受信するまで、すべてが正常に機能します。その後、メモリ リークが発生します。

Instrumentsは、リークされたオブジェクトが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 (抜粋)

#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

それは私をちょっと夢中にさせています:)

4

3 に答える 3

0

私のアドバイスは、iOS 自体が生成する 1 回限りのメモリ リークに取りつかれないようにすることです。それは多くの場所でこれを行い、リークはすべてかなり無害です.

于 2010-08-21T01:03:41.010 に答える
0

ああ、ずっと前に終わった問題、私は彼らが大好きです。

locationController はプロパティではなく iVar であるため、viewDidLoad で作成した場合、_locationController に割り当てても所有権は取得されません。

オブジェクトを自動解放したので、次回のイベント ループでは、自動解放プールが空になり、解放されます。

保持プロパティにするか( locationManager = nil に適合)、自動解放を取り除き、dealloc で明示的な [locationManager release] を使用することで修正できます。

于 2013-10-22T15:56:10.323 に答える
-1

やってみてくださいBuild and Analyze。私は通常、メモリリークやその他の構文エラー以外のエラーをそのように見つけます。

于 2010-08-21T01:30:13.253 に答える