简体   繁体   中英

What is initWithCoder actually doing when used in conjunction with a core location manager object?

Ok so I'd like to full understand what is going on in this piece of code with initWithCoder. Here's what I think is going on after reading through several suggested docs and reading chapters from a book on delegation, core location, designated initializers over and over again.

  • Initialize my viewcontroler with a pointer to an NSCoder object.
  • If that works then create an instance of a location manager object
  • Make the delegate my viewcontroller.
  • Set location accuracy to best.
  • Tell the location manager to start updating.

  • Log the info "stored in the delegate" to console. The lat and long are stored in a pointer to an NSArray object that is passed in as an argument to locationManager:DidUpdateLocations: method.

  • If location was not found also log this status in console.

.h interface file:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface WhereamiViewController : UIViewController
{
    CLLocationManager *locationManager;

}

@end

.m implementation file:

#import "WhereamiViewController.h"

@interface WhereamiViewController ()

@end

@implementation WhereamiViewController

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self){
        //create location manager object
        locationManager = [[CLLocationManager alloc] init];

        //there will be a warning from this line of code
        [locationManager setDelegate:self];

        //and we want it to be as accurate as possible
        //regardless of how much time/power it takes
        [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

        //tell our manager to start looking for its location immediately
        [locationManager startUpdatingLocation];
    }

    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateLocations:(NSArray *)locations
{
    NSLog(@"%@", locations);
}

- (void)locationManager:(CLLocationManager *)manager
      didFailWithError:(NSError *)error
{
    NSLog(@"Could not find location: %@", error);
}


@end

Some further questions:

1) Is the setDelegate part of the code important because that is where the the "startUpdatingLocation method will store it's data?

2) Is the data stored archived? I asked because the fact that the delegate I set has the initializer initWithCoder. Which from what I've read is an unarchiver of archived data. So maybe the info from locationManager is archived and needs to be un-archived if that makes sense.

I get this warning on XCode. Am I doing something wrong? 在此输入图像描述 Am I still suppose to set delegates this way or is there a new way of doing so? in another post I remember seeing an answer with something like <UIViewControllerDelegate> and was told to put this in my interface file.

I realise that most of this post may not make sense and I may be totally wrong but I learn most from my failures and maybe others will in future if they choose to learn to develop for ios.

Thanks for your time.

Regards

1) Is the setDelegate part of the code important because that is where the the "startUpdatingLocation method will store it's data?

Yes, you won't be able to receive the data from CLLocationManager as it won't know on which object to call locationManager:didUpdateLocations: , locationManager:didFailWithError: and other methods you haven't implemented yet. You should get accustomed with the delegate pattern in Objective-C .

2) Is the data stored archived? I asked because the fact that the delegate I set has the initializer initWithCoder. Which from what I've read is an unarchiver of archived data. So maybe the info from locationManager is archived and needs to be un-archived if that makes sense.

The data won't be archived, because you don't store it anywhere. CLLocationManager also doesn't store the data anywhere.

I get this warning on XCode. Am I doing something wrong?

You're missing the declaration that your view controller conforms to CLLocationManagerDelegate protocol. You can fix it by replacing:

@interface WhereamiViewController ()

with:

@interface WhereamiViewController () <CLLocationManagerDelegate>

You should read about working with protocols in Objective-C .

Overall, yes.

1) Yes, it's important. It tells the location manager who wants to know about location updates. startUpdatingLocation isn't storing data in the delegate. startUpdatingLocation triggers the location system to start up and find out where you are. The delegate gets told about the location and can do what it wants with it.

2) initWithCoder recreates the WhereamiViewController from an archive. That archive is most likely an XIB or storyboard. It has nothing to do with the location manager or delegate relationship.

As @ArkadiuszHolko says, you should be specifying <CLLocationManagerDelegate> . The purpose of this is to tell the compiler that you promise to implement the required methods of the protocol, so it can check that you do an raise an issue otherwise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM