CLLocationManager - 奇怪的内存泄漏

3

我正在实现一个CLLocationManager,就像教程中描述的那样。

一切都很好,直到LocationManager接收到第二个更新。这时就会发生内存泄漏。

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

然后,在主类中我调用:
主文件.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

这让我有点疯狂 :)


每次过了100秒后,应用程序会崩溃吗?因为你正在向一个不实现该消息方法的对象发送延迟消息。由于您释放了位置管理器但仍保留对其的引用,因此它也应该随机崩溃。 - Jason Coco
@Swissdude有这个问题的解决方案吗? - name-it
那么,这是Location框架的真正内存泄漏吗?还是在你的代码中出现了问题? - Itay Levin
3个回答

0

啊,一个已经解决的问题,我喜欢它们。

locationController是一个iVar,而不是一个属性,所以当你在viewDidLoad中创建它并将其分配给_locationController时,它不会拥有所有权。

你已经自动释放了这个对象,所以下一次事件循环时,自动释放池被清空并且它被释放。

你可以通过将其设置为retain属性(这将与你的locationManager = nil相适应)来修复它,或者摆脱自动释放,并在dealloc中使用显式的[locationManager release]。


0

我的建议是不要过于关注iOS本身生成的一次性内存泄漏。它在许多地方都会出现,而且这些泄漏都相当无害。


但是应用程序在一段时间后崩溃了 - 所以我想我应该关注一下 ;) - Swissdude
如果你遇到了更大的问题,那么请发布更多的代码以便我们提供提示。 - Stefan Arentz
如果你的应用崩溃了,很不可能是由于一个小的iOS内部泄漏所导致的。如果你需要帮助,请在另一个问题中发布崩溃日志。 - raidfive

-1
尝试进行“构建和分析”操作。我通常通过这种方式发现内存泄漏和其他非语法错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接