嗨,我正在玩iPhone的位置,从一开始就遇到了问题。我已经对我的问题进行了本地化,并确定它是CLLocationManager
,这让我烦恼。
所以我开发了非常简单的应用程序。我只有一个带有CLLocationManager
的视图控制器。在视图上加载我初始化CLLocationManager
并开始更新。我还实现了两种方法didFailWithError
和didUpdateToLocation
。
我已经阅读了很多问题以及我学到了什么,所以这就是这个。您必须在初始化期间保留CLLocationManager
。在卸载CLLocationManagers
期间将delegate
nil
设置为view
也是明智的(与传递给CLLocationManager
的消息有关,因为框架会保留它并且它永远不会正确释放)
总而言之,我无法找到关于如何做以及如何使其发挥作用的合理解释。
这是我的代码,所以如果有人能搞清楚,我会很感激。
viewControllers
头文件
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface CoreLocationViewController : UIViewController <CLLocationManagerDelegate>
{
CLLocationManager *locManager;
}
@property (nonatomic, retain) CLLocationManager *locManager;
@end
viewController .m文件
#import "CoreLocationViewController.h"
@implementation CoreLocationViewController
@synthesize locManager;
- (void)viewDidLoad
{
[super viewDidLoad];
self.locManager = [[CLLocationManager alloc] init];
locManager.delegate = self;
[self.locManager startUpdatingLocation];
self.view.backgroundColor = [UIColor grayColor];
}
#pragma mark -
#pragma mark Location Delegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"in fail with error");
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"in update to location");
}
#pragma mark -
#pragma mark Memory Management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload
{
self.locManager.delegate = nil;
[super viewDidUnload];
}
- (void)dealloc
{
[locManager release];
[super dealloc];
}
@end
BTW:我使用的是iOS 4.2。我指出这一点是因为我读到Apple已经改变了iOS 4中的位置代表
答案 0 :(得分:20)
在我的情况下,代理永远不会因为线程问题而被调用
答案 1 :(得分:8)
此外,在iOS8中,你必须有两件额外的东西:
在Info.plist中添加一个密钥,并请求位置管理员授权启动。
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
您需要请求相应位置方法的授权。
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
代码示例:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
来源:http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
答案 2 :(得分:4)
其他海报提到检查授权,你一定要加上,但我不认为这是你的问题。如果您未获得授权,则会调用didFailWithError:
方法。这导致相信其他事情正在发生。
确保您的位置管理员确实被分配是一个好主意,而在此期间,您可以修复内存泄漏。
试试这个:
CLLocationManager* lm = [[CLLocationManager alloc] init];
NSAssert(lm != nil, @"Failed to allocate CLLocation manage");
self.locManager = lm;
[lm release];
self.locManager.delegate = self;
[self.locManager startUpdatingLocation];
// Let's just print what we got
NSLog(@"CLLocationManager is %@", lm);
如果您执行此操作,您将获得以下结果之一:
1)如果位置管理器返回nil,程序将崩溃到调试器中(因为NSAssert)
2)如果“CLLocationManager is ....”打印并且你仍然没有看到任何更新,那么你手上就会有一个真正的神秘面纱。
3)没有打印。这可能意味着,可能是由于Interface Builder中错误链接的东西,viewDidLoad根本没有被调用。
4)您将获得didFailWithError:
电话,因为您未获得授权。这意味着至少一切都按预期工作。
另外,您有内存泄漏,因为您将alloc的结果直接分配给具有retain
属性的属性。在分配之后,你的计数在分配后将是+1 + +,所以如果视图被卸载并重新加载,你就会泄漏。
希望其中一些有用。
答案 3 :(得分:3)
这可能是挑剔但在viewDidLoad更改:
locManager.delegate = self;
为:
self.locManager.delegate = self;
我不知道它是否会修复它,但最好保持一致。
答案 4 :(得分:3)
所以我设法找到了一个bug。这是在内存管理。在我的app委托文件中,我初始化了一个CoreLocationViewController
并将其作为subview
添加到了我的窗口,之后我发布了它,一切都很顺利。但是,释放部分不是一个好方法。在我发布ViewController
后,dealloc
方法被调用并释放locationManager
。
因此,正确的做法是不释放持有ViewController
的{{1}},或者找到另一种处理它的方法。我不太确定为什么这是一个问题,因为我认为在向窗口添加locationManager
之后它会被保留,因此它的ViewController
也会被保留。如果有人能为我清理它,我将不胜感激。
答案 5 :(得分:2)
if (self.locManager.locationServicesEnabled){
//do domething
}
答案 6 :(得分:0)
Idk如果是一件事,但在我的代码中我也设置了所需的准确度
[locManager setDesiredAccuracy:kCLLocationAccuracyBest];
例如。
答案 7 :(得分:0)
试试这个:
NSLog(@"location services enabled: %d", [locManager locationServicesEnabled]);
来自文档:
用户可以通过在设置&gt;中切换开关,从设置应用程序中完全启用或禁用位置服务。一般&gt;位置服务。
答案 8 :(得分:0)
我遇到了同样的问题,正如paxx所说,这是一个内存管理问题。我的解决方案是手动保留'self'。如下面的代码所示:
- (void) viewDidload
{
[super viewDidload];
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"Location Service Disabled!");
} else {
[self retain];
//initialize the cllocationmanager obj.
}
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
//do your surf
[self release];
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
//do your stuff
[self release];
}
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
//do your stuff
[self release];
}
不漂亮,但对我来说很好。