Search code examples
iosobjective-cnskeyedunarchiver

iOS NSKeyedUnarchiver not get correct value


I simplify the code for ask question.

I want to save more class and load class model file.

But now I simplify parameters to one part (lim) in the model(FlightSettingModel.h).

In the FlightSettingModel.h I have set some parameters in here.

FlightSettingModel.h code below:

 #import <Foundation/Foundation.h>

 @interface FlightSettingModel : NSObject<NSCoding>

 // lim property part
 @property float limCurrentVal;
 @property float limDefaultVal;
 @property float limMaxVal;
 @property float limMinVal;

 // .... other property part
 @end

FlightSettingModel.m code below

 #import "FlightSettingModel.h"
 @interface FlightSettingModel()
 {
 }
 @end
 @implementation FlightSettingModel

 -(instancetype)init
 {
     self = [super init];
     if(self)
     {
    
         self.limDefaultVal = 3.0;
         self.limCurrentVal = 4.0;
         self.limMaxVal = 10;
         self.limMinVal = 0;   

         // ... other property part value init .....     
     }
     return self;
 }


 - (void)setFlightSettingToDefaultValue
 {
     self.limCurrentVal = self.limDefaultVal;

 }



 - (void) encodeWithCoder: (NSCoder *)encoder
 {
     [encoder encodeFloat:self.limCurrentVal forKey:@"limCurrentVal"];

 }


 - (id)initWithCoder:(NSCoder *)decoder {
     if((self = [super init])) {
         self.limCurrentVal = [decoder decodeFloatForKey:@"limCurrentVal"];

     }
     return self;
 }
 @end

Then I have set the singleton SettingData file to initial the FlightSettingModel and other model class.

The SettingData model header like below:

 #import <Foundation/Foundation.h>
 #import "FlightSettingModel.h"

 @interface SettingData : NSObject

 @property (nonatomic,strong) FlightSettingModel *flightSettingModel;
 +(SettingData*) sharedInstance;

 @end

SettingData.m code below:

 #import "SettingData.h"

 @implementation SettingData

 SettingData *sharedInstance;

 +(SettingData*) sharedInstance{
     if( sharedInstance == nil )
     {
         sharedInstance = [SettingData new];
    
     }
     return sharedInstance;
 }

 -(id) init{
     self = [super init];

     if( self )
     {
    
         self.flightSettingModel = [FlightSettingModel new];
     }

     return self;
 }

 @end

In my storyboard (UI) is like below:

enter image description here

When I click the save button , I want to save the custom class model(FlightSettingModel.h) in the NSKeyedArchiver. When I click the load, I want to load the model from the archiver using NSKeyedUnarchiver and resetting to the slider.

But now,when I drag the slider to other value(ex:10), then I click the save, then I close the app restart the app. I click the load, the slider value will become 0.

I don't know why when I load the value the all value will become 0;

My view controller code .m below:

    #import "ViewController.h"
    #import "SettingData.h"

    @interface ViewController ()
    {
    NSString *path;
    NSString *fileName;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

// file manage
    path =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
    fileName = [path stringByAppendingPathComponent:@"flightFile"];

    [self setUIValue];

    NSLog(@"---");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}

- (IBAction)saveAction:(UIButton *)sender {

    [NSKeyedArchiver archiveRootObject:[SettingData sharedInstance].flightSettingModel toFile:fileName];
}

- (IBAction)loadAction:(UIButton *)sender {

    [SettingData sharedInstance].flightSettingModel  =   (FlightSettingModel*) [NSKeyedUnarchiver unarchiveObjectWithFile: fileName];
    [self setUIValue];

    NSLog(@"current Value:%.f",[SettingData sharedInstance].flightSettingModel.limCurrentVal);
}

- (IBAction)sliderChangedAction:(UISlider *)sender {
    [SettingData sharedInstance].flightSettingModel.limCurrentVal = sender.value;
    self.theTextField.text =  [NSString stringWithFormat:@"%.f",self.theSlider.value];
}

-(void) setUIValue
{
    // setting slider property
    self.theSlider.maximumValue = [SettingData sharedInstance].flightSettingModel.limMaxVal;
    self.theSlider.minimumValue = [SettingData sharedInstance].flightSettingModel.limMinVal;
    self.theSlider.value = [SettingData sharedInstance].flightSettingModel.limCurrentVal;

    self.theTextField.text = [NSString stringWithFormat:@"%.f",self.theSlider.value];

}

@end

Have anyone know where my problem in my code?

thank you very much.

If you want to download the complete code(the question code) , I have upload in github


Solution

  • This behavior happens because the [SettingData sharedInstance].flightSettingModel.limMaxVal and the [SettingData sharedInstance].flightSettingModel.limMinVal are zero:

    -(void) setUIValue
    {
        // setting slider property
        self.theSlider.maximumValue = [SettingData sharedInstance].flightSettingModel.limMaxVal;
        // self.theSlider.maximumValue = 0
        self.theSlider.minimumValue = [SettingData sharedInstance].flightSettingModel.limMinVal;
        // self.theSlider.minimumValue = 0
        self.theSlider.value = [SettingData sharedInstance].flightSettingModel.limCurrentVal;
        // [SettingData sharedInstance].flightSettingModel.limCurrentVal = 10
    
        self.theTextField.text = [NSString stringWithFormat:@"%.f",self.theSlider.value];
    
    }
    

    EDIT: You can fix it by adding this:

    - (void) encodeWithCoder: (NSCoder *)encoder {
        [encoder encodeFloat:self.limCurrentVal forKey:@"limCurrentVal"];
        [encoder encodeFloat:self.limMaxVal forKey:@"limMaxVal"];
        [encoder encodeFloat:self.limMinVal forKey:@"limMinVal"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder {
        if((self = [super init])) {
            self.limCurrentVal = [decoder decodeFloatForKey:@"limCurrentVal"];
            self.limMaxVal = [decoder decodeFloatForKey:@"limMaxVal"];
            self.limMinVal = [decoder decodeFloatForKey:@"limMinVal"];
        }
        return self;
    }