首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >归档和取消归档数据/模型对象

归档和取消归档数据/模型对象
EN

Stack Overflow用户
提问于 2014-01-17 18:06:00
回答 1查看 346关注 0票数 0

我遵循MVCS范例,在与更新地图数据相关的测试应用程序中保存并加载数据对象的实例。

BNRMapPoint.h

代码语言:javascript
复制
 #import <Foundation/Foundation.h>
 #import <MapKit/MapKit.h>
 #import <CoreLocation/CoreLocation.h>
 @interface BNRMapPoint : NSObject<MKAnnotation, NSCoding>
 {
     double latitude;
     double longitude;
     @public NSArray *mapPoints;
 }
-(id) initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t subTitle:(NSString *)st;

 //this is required property in MKAnnotation Protocol
 @property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

 //this is an optional property in MKAnnotation Protocol
 @property (nonatomic, copy) NSString *title;
 //this is an optional property in MKAnnotation Protocol
 @property (nonatomic,readonly,copy) NSString *subTitle;
 @end

BNRMapPoint.m (模型)

代码语言:javascript
复制
#import "BNRMapPoint.h"

@implementation BNRMapPoint
@synthesize coordinate=_coordinate;
@synthesize title=_title;
@synthesize subtitle=_subtitle;

-(void)encodeWithCoder:(NSCoder *)aCoder{
  latitude  = self.coordinate.latitude;
  longitude = self.coordinate.longitude;

  [aCoder encodeObject:self.title forKey:@"title"];
  [aCoder encodeObject:_subTitle forKey:@"subTitle"];
  [aCoder encodeDouble: latitude forKey:@"latitude"];
  [aCoder encodeDouble:longitude forKey:@"longitude"];
}
-(id)initWithCoder:(NSCoder *)aDecoder{
   if (self= [super init]) {
      [self setTitle:[aDecoder decodeObjectForKey:@"title"]];
       self->_subTitle= [aDecoder decodeObjectForKey:@"subTitle"];
       latitude= [aDecoder decodeDoubleForKey:@"latitude"];
       longitude= [aDecoder decodeDoubleForKey:@"longitude"];
   }
   return self;
}

-(id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t subTitle:(NSString *)st{
  if (self= [super init]) {
    self.coordinate=c;
    self.title=t;
    _subtitle=st;
   }
   return self;
}
  -(id) init{
    return  [self initWithCoordinate:CLLocationCoordinate2DMake(43.07, -89.32) title:@"Hometown"   subTitle:self.subtitle];
}

@end

WhereamiViewController.h

代码语言:javascript
复制
   #import <UIKit/UIKit.h>
   #import <CoreLocation/CoreLocation.h>
   #import <MapKit/MapKit.h>
   #import "BNRMapPoint.h"
   #import "RootObject.h"
  @interface WhereamiViewController :      UIViewController<CLLocationManagerDelegate,MKMapViewDelegate,UITextFieldDelegate>
   {
        @public RootObject *rootObj;
        CLLocationManager *locationManager;

        IBOutlet MKMapView *worldView;
        IBOutlet UIActivityIndicatorView *activityIndicator;
        IBOutlet UITextField *locationTitleField;
   }
   -(IBAction)buttonDidGetPressed:(id)sender;
   -(BOOL)textFieldShouldReturn:(UITextField *)textField;
    -(void)findLocation;
    -(void)foundLocation:(CLLocation *)loc;

   @end

WhereamiViewController.m amiViewController.m (ViewController)

代码语言:javascript
复制
    #import "WhereamiViewController.h"

    @interface WhereamiViewController ()

    @end

    @implementation WhereamiViewController

    -(IBAction)buttonDidGetPressed:(UISegmentedControl *)sender{//Silver challenge
      NSLog(@"%@",NSStringFromSelector(_cmd));
        if([sender selectedSegmentIndex]==0){
           [worldView setMapType:MKMapTypeStandard];
        }
        else if([sender selectedSegmentIndex]==1){
           [worldView setMapType:MKMapTypeHybrid];
        }
        else if([sender selectedSegmentIndex]==2){
            [worldView setMapType:MKMapTypeSatellite];
        }
     }
      -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
           NSLog(@"%@", NSStringFromSelector(_cmd));
         if (self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
             rootObj= [[RootObject alloc] init];
            locationManager= [[CLLocationManager alloc] init];

            [locationManager setDelegate:self];//self is Whereamicontroller. The delegate pointer is of type id<CLLocationManagerDelegate> and is an ivar of CLLocationManager.
            [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];      
          }
          NSLog(@"test");
         return self;
      }

      -(void) viewDidLoad{
          //    [worldView setMapType:MKMapTypeSatellite]; Bronze challenge
           [worldView setShowsUserLocation:YES];
       }
       -(void)findLocation{
           NSLog(@"%@",NSStringFromSelector(_cmd));
          [locationManager startUpdatingLocation];//This calls locationManager:didUpdateLocations:
           NSLog(@"location updated");
            [activityIndicator startAnimating];
            [locationTitleField setHidden:YES];
       }
       -(BOOL)textFieldShouldReturn:(UITextField *)textField{
           NSLog(@"%@",NSStringFromSelector(_cmd));
           [self findLocation];
           [textField resignFirstResponder];
           return YES;
       }

       -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
           NSLog(@"%@",NSStringFromSelector(_cmd));
            CLLocationCoordinate2D centerCoordinate= [[userLocation location] coordinate]; //get the coordinate of current location.
             MKCoordinateSpan span= MKCoordinateSpanMake(250, 250);//Structure members
             MKCoordinateRegion mapPortionToDisplay= MKCoordinateRegionMakeWithDistance(centerCoordinate, span.latitudeDelta, span.longitudeDelta);//span.latitudeDelta=250 and span.longitudeDelta=250
             [worldView setRegion:mapPortionToDisplay animated:YES];
            //    [worldView setRegion:mapPortionToDisplay];
       }

       -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
          NSLog(@"%@",NSStringFromSelector(_cmd));
          NSLog(@"Heading %@",newHeading);
       }
       -(void)foundLocation:(CLLocation *)loc{
            NSLog(@"%@",NSStringFromSelector(_cmd));
            CLLocationCoordinate2D coord= [loc coordinate];

            NSDateFormatter *formatter= [[NSDateFormatter alloc] init];

            NSDate *currentDate= [[NSDate alloc] init];
            [formatter setDefaultDate:currentDate];

             BNRMapPoint *bmp= [[BNRMapPoint alloc] initWithCoordinate:coord title:[locationTitleField text] subTitle:[[formatter defaultDate] description]];
            [rootObj.mapPoints addObject:bmp];

             [worldView addAnnotation:bmp];

             MKCoordinateRegion region= MKCoordinateRegionMakeWithDistance(coord,250,250);
             [worldView setRegion:region animated:YES];

              //RESET the UI
             [locationTitleField setText:@" "];
             [activityIndicator stopAnimating];
             [locationTitleField setHidden:NO];
              [locationManager stopUpdatingLocation];
        }
         -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //CLLocationManagerDelegate method implementation

           NSLog(@"%@", NSStringFromSelector(_cmd));
        //    NSTimeInterval t0=[[locations lastObject] timeIntervalSinceNow];

          NSLog(@"%@",(CLLocation *)[locations lastObject]);
          NSTimeInterval t= [[(CLLocation *)[locations lastObject] timestamp] timeIntervalSinceNow];

           if (t<-180) {
             return; //No op
           }

           [self foundLocation:[locations lastObject]];

        }

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


         @end

RootObject.h

代码语言:javascript
复制
       #import <Foundation/Foundation.h>

       @interface RootObject : NSObject
       @property NSMutableArray *mapPoints;
       -(BOOL)saveChanges;
       -(NSString *)dataObjectArchivePath;
       @end

RootObject.m (Store)

代码语言:javascript
复制
      #import "RootObject.h"

       @implementation RootObject
        @synthesize mapPoints;

     -(NSString *)dataObjectArchivePath{
         NSArray *documentDirectories= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
         NSString *documentDirectory= [documentDirectories objectAtIndex:0];

          NSString *finalPath= [documentDirectory stringByAppendingPathComponent:@"items.archive"];
         return finalPath;
      }
      -(BOOL)saveChanges{
          NSString *path= [self dataObjectArchivePath];
          return [NSKeyedArchiver archiveRootObject:self.mapPoints toFile:path];writing to the file items.archive
      }
      -(id)init{
          if (self=[super init]) {
             NSString *path= [self dataObjectArchivePath];
             self.mapPoints= [NSKeyedUnarchiver unarchiveObjectWithFile:path];//reading from the file items.archive

          if (!self.mapPoints) {
              self.mapPoints= [[NSMutableArray alloc] init];
        }
      }
      return self;
     }
     @end

AppDelegate.m

代码语言:javascript
复制
     - (void)applicationDidEnterBackground:(UIApplication *)application
      {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
         // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
        NSLog(@"%@",NSStringFromSelector(_cmd));
         BOOL success= [[BNRItemStore sharedStore] saveChanges];
        if (success) {
           NSLog(@"Saved all of the BNRItems");
        }
        else{
         NSLog(@"Could not save any of the BNRItems");
        }
     }

在上面的代码中,从application: didEnterBackground:调用了saveChanges方法。所以我还没有为Store (RootObject)创建一个单例对象。但我在viewController的指定初始化器中实例化了它。要存档的数据是BNRMapPoint对象。在进入背景状态时,代码确实成功地保存了对象。然而,在重新启动应用程序后,initWithCoder被卡住了。在读取之前保存的MapPoint对象时,应用程序会崩溃。请帮帮忙..我已经检查过了几乎是可能的。不知道该怎么办。我被卡住了。

EN

回答 1

Stack Overflow用户

发布于 2014-01-17 19:13:58

所以问题是你有:

代码语言:javascript
复制
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; 

并且您正在尝试对只读属性使用setter:

代码语言:javascript
复制
self.coordinate=c;

这就是为什么它说无法识别的选择器是send -因为它是只读的,所以setter不存在。使用此was属性等同于调用:

代码语言:javascript
复制
[self setCoordinate:c]

只需将属性设置为可分配

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21183055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档