关于 Objective-C 中的委托、CLLocationManager 的问题
我对委托的运作方式感到有点困惑。我相信这个想法是让另一个班级为你完成工作并给你回电。因此,如果你做了这样的事情:
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if (CLLocationManager.locationServicesEnabled == YES) {
NSLog(@"location enabled");
latitudeLabel.text = [NSString stringWithFormat:@""];
[locationManager startUpdatingLocation];
}
NSLog(@"%g", locationCoordinate.latitude);
}
如果我在 viewDidLoad 中 NSLog 坐标,即使我 startUpdatingLocation,我的 locationCoordinate 属性的值也是 0。但是如果我像这样 NSLog 委托方法中的值:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSString *latitudeString = [[NSString alloc] initWithFormat: @"%g m", newLocation.coordinate.latitude];
latitudeLabel.text = latitudeString;
[latitudeString release];
locationCoordinate = newLocation.coordinate;
NSLog(@"in delegate: %g", locationCoordinate.latitude);
}
我得到一个实际位置值。我认为通过使用委托方法,我的 locationProperty 会被设置,但似乎没有。我对委托的理解是否错误?谢谢。
I'm getting a bit confused how delegation works. I believe the idea is to have another class do the work for you and call you back. So if you did something like this:
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if (CLLocationManager.locationServicesEnabled == YES) {
NSLog(@"location enabled");
latitudeLabel.text = [NSString stringWithFormat:@""];
[locationManager startUpdatingLocation];
}
NSLog(@"%g", locationCoordinate.latitude);
}
If I NSLog the coordinate in the viewDidLoad, even though I startUpdatingLocation, the value of my locationCoordinate property is 0. But if I NSLog the value in the delegate method like so:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSString *latitudeString = [[NSString alloc] initWithFormat: @"%g m", newLocation.coordinate.latitude];
latitudeLabel.text = latitudeString;
[latitudeString release];
locationCoordinate = newLocation.coordinate;
NSLog(@"in delegate: %g", locationCoordinate.latitude);
}
I get an actual location value. I thought that by using the delegate method, my locationProperty would get set, but it seems not to. Am I understanding delegation incorrectly? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
事实上,代表存在的一个主要原因就是在您所描述的情况下。
您在一个类中有一些功能,但该功能是异步的,即您不能立即获取信息,或者它是异步实现的(例如,从网上下载一个大文件应该/确实会异步发生,一分钟不锁定整个界面+)。
因此,使用委托时,您可以说“只需成为我的代表,我最终会回复您,我们现在就完成了”。然后,该对象可以在方便时返回给调用者,而不是相反(仅在主应用程序需要时才被调用)。
如前所述,下载文件等正是委托发挥作用的地方。对于您自己的编码来说,它也是一个非常有用的工具,可以在您的代码中合并委托,以防您必须等待来自其他对象(例如 CLLocationManager)的委托,或者您必须处理某些内容在单独的线程上(例如解析数据或其他)。
A major reason why delegates exist is in fact in situations like the one you describe.
You have some functionality in a class, but the functionality is asynchronous, i.e. you can't just go get the info right off the bat, or it's implemented asynchronously (for example, downloading a huge file off the net should/does happen asynchronously, to not lock up the whole interface for a minute+).
So using delegation you can say "just become my delegate and I'll eventually get back to you, we're done for now". The object can then return back to the caller at its convenience, rather than the opposite (being called only when the main application wants it).
As said, downloading files and such is exactly where delegation comes into play. It's also a very useful tool for your own coding to incorporate delegates in your code, in cases where you either have to wait on delegation from some other object (such as CLLocationManager), or you have to process something on a separate thread (such as parsing data or whatnot).
委托给您带来的唯一好处是 locationManager 调用您的委托方法。对象通常不会更改其委托的属性。
因此,为了确保您的坐标属性得到更新,您必须按照您的方式实现 CLLocationManager 的委托方法。
实际上,我建议您根本不要使用 locationCooperative 属性,而是使用 LocationManager 的位置属性。
The only thing the delegation gets you is that the locationManager calls your delegate method(s). Objects usually do not change their delegate's properties.
So to be sure that your coordinate property is updated, you'd have to implement the CLLocationManager's delegate method the way you did.
Actually I'd suggest you don't use the locationCoordinate property at all and instead use the LocationManager's location property.
启用位置服务后,需要一段时间才能获得位置值。这可能就是您在第一个示例中没有得到结果的原因。 (我认为您必须调用 startUpdatingLocation 方法)。
这里委托的想法是,您设置为委托的类或多或少承诺实现调用者可以在他认为有必要时调用的方法。
正如第二个示例中的方法签名所暗示的那样,Locationmanager 是知道发生更新的人,并且委托使他能够采取行动。
如果您不使用类似的东西,则必须定期查询位置变化
After you enable location services it takes a time until the values for location are there. That's probably why you don't get results in you first example. ( that and I think you must call the startUpdatingLocation method ).
The idea with the delegate here is that the class that you set as a delegate more or less promises to implement methods that the caller can then call whenever HE thinks it's necessary.
As the method signature in your second example implies, the Locationmanager is the one who knows about updates happening, and the delegate enables him then to take action.
If you would not use something like that, you would have to query for changes in location periodically
要了解这里发生的情况,您应该首先尝试了解委托模式。它是一种面向对象的模式,适用于多种语言:
http://en.wikipedia.org/wiki/Delegation_pattern
在这种情况下,CLLocationManager 执行查找位置的任务。当它完成这个任务时,它知道您可能想用它收集的信息做一些事情,但它并不真正知道做什么。通过将“self”设置为委托,您将告诉 CLLocationManager,当完成获取位置后,您将负责接下来发生的事情。您可以通过实现 locationManager 委托方法来做到这一点。当位置管理器找到位置后,它将调用该方法,但在此之前不会。在您的第一个 NSSLog 中,您正在查看位置管理器确定当前纬度之前的纬度。
To understand what is going on here you should first try to understand the delegation pattern. It is an object oriented pattern that applies to many languauges:
http://en.wikipedia.org/wiki/Delegation_pattern
In this case CLLocationManager performs the task of finding the location. When it is done with this task it knows that you probably want to do something with the information it gathered but it doesn't really know what. By setting "self" as the delegate you are telling CLLocationManager that when it's done getting the location you will take care of what happens next. You do that by implementing the locationManager delegate method. When the location manager is done finding the location it will call that method, but not before then. In your first NSSLog you are looking at the latitude before the location manager has figured out what the current latitude it is.