Переменные теряют свои значения, прежде чем я могу сохранить их в plist

Я пишу класс контроллера для своего plist, который вызывается из другого класса. класс контроллера имеет метод чтения и сохранения, метод чтения открывает plist и сохраняет его в файле документов для чтения и записи. В этом классе чтения я помещаю все значения, которые были сохранены ранее, в их собственные переменные.

Затем в вызове метода Save, который вызывается из другого класса, все значения передаются в качестве параметров, затем оттуда я передаю новые значения в правильные переменные и передаю их в plist.. однако у меня есть словарь внутри моего plist и он сохраняет только одно значение и сбрасывает остальные на нуль. Мне интересно, как мне убедиться, что эти переменные сохраняют свои значения?

Вот мой .ч

#import <Foundation/Foundation.h>

@interface EngineProperties : NSObject {

NSString *signature;
NSNumber *version;
NSNumber *request;
NSNumber *dataVersion;
NSMutableDictionary *cacheValue;
//cachevalue Items
NSNumber *man;
NSNumber *mod;
NSNumber *sub;

}

@property (copy, nonatomic) NSString *signature;
@property (copy, nonatomic) NSNumber *version;
@property (copy, nonatomic) NSNumber *request;
@property (copy, nonatomic) NSNumber *dataVersion;
@property (copy, nonatomic) NSMutableDictionary *cacheValue;
//cachevalue Items
@property (copy, nonatomic) NSNumber *man;
@property (copy, nonatomic) NSNumber *mod;
@property (copy, nonatomic) NSNumber *sub;



- (void) readPlistData;
- (void) saveData:(NSString *)methodName signature:(NSString *)pSignature Version:(NSNumber *)pVersion request:(NSNumber *)rNumber dataVersion:(NSNumber *)dvReturned cacheValue:(NSNumber *)cValue;

@end

а вот мой .м

#import "EngineProperties.h"

@implementation EngineProperties

@synthesize signature;
@synthesize version;
@synthesize request;
@synthesize dataVersion;
@synthesize cacheValue;

@synthesize man;
@synthesize mod;
@synthesize sub;



//This opens up and reads the current plist ready to be used
-(void) readPlistData
{
    // Data.plist code
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"EngineProperties.plist"];

    // check to see if Data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
    {
        // if not in documents, get property list from main bundle
        plistPath = [[NSBundle mainBundle] pathForResource:@"EngineProperties" ofType:@"plist"];
    }

    // read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    // convert static property liost into dictionary object
    NSDictionary *tempRoot = (NSMutableDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    if (!tempRoot)
    {
        NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
    }
    // assign values
    self.signature = [tempRoot objectForKey:@"Signature"];
    self.version = [tempRoot objectForKey:@"Version"];
    self.request = [tempRoot objectForKey:@"Request"];
    self.dataVersion = [tempRoot objectForKey:@"Data Version"];

    man = [cacheValue objectForKey:@"Man"];
    mod = [cacheValue objectForKey:@"Mod"];
    sub = [cacheValue objectForKey:@"SubMod"];

    cacheValue = [tempRoot objectForKey:@"Cache Value"];
}


- (void) saveData:(NSString *)methodName signature:(NSString *)pSignature Version:(NSNumber *)pVersion request:(NSNumber *)rNumber dataVersion:(NSNumber *)dvReturned cacheValue:(NSNumber *)cValue;
{
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"EngineProperties.plist"];

    // set the variables to the values in the text fields
    self.signature = pSignature;
    self.version = pVersion;
    self.request = rNumber;
    self.dataVersion = dvReturned;

    //do some if statment stuff here to put the cache in the right place or what have you.
    if (methodName == @"manufacturers")
    {
        self.man = cValue; 
    }
    else if (methodName == @"models")
    {
        self.mod = cValue;
    }
    else if (methodName == @"subMod")
    {
        self.sub = cValue;
    }

    self.cacheValue = [NSDictionary dictionaryWithObjectsAndKeys:
                       man, @"Manufacturers",
                       mod, @"Models",
                       sub, @"SubModels", nil];


    NSDictionary *plistDict = [NSDictionary dictionaryWithObjectsAndKeys:
                               signature, @"Signature",
                               version, @"Version",
                               request, @"Request",
                               dataVersion, @"Data Version",
                               cacheValue, @"Cache Value", nil];



    NSString *error = nil;
    // create NSData from dictionary
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

    // check is plistData exists
    if(plistData)
    {
        // write plistData to our Data.plist file
        [plistData writeToFile:plistPath atomically:YES];

        NSString *myString = [[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding];
        //        NSLog(@"%@", myString);
    }
    else
    {
        NSLog(@"Error in saveData: %@", error);
        //        [error release];
    }
}


@end

Я пытаюсь выяснить, как сохранить правильные значения в этих трех переменных, man, mod, sub, чтобы я мог поместить их в свой словарь значений кеша.


person C.Johns    schedule 05.04.2012    source источник


Ответы (2)


Проблема в том, что когда вы готовите свои данные для создания словаря, здесь:

if (methodName == @"manufacturers")
{
    self.man = cValue; 
}
else if (methodName == @"models")
{
    self.mod = cValue;
}
else if (methodName == @"subMod")
{
    self.sub = cValue;
}

Это неправильный способ сравнения строк (на самом деле вы сравниваете адреса строк, поэтому они, вероятно, никогда не будут одинаковыми), вместо этого вы должны использовать это:

if ([methodName isEqualToString:@"manufacturers"])
{
    self.man = cValue; 
}
else if ([methodName isEqualToString:@"models"])
{
    self.mod = cValue;
}
else if ([methodName isEqualToString:@"subMod"])
{
    self.sub = cValue;
}

Другая проблема заключается в том, что в readPlistData вы читаете ключи «Man», «Mod» и «SubMod», но они должны быть такими же, как вы записываете в словарь: «Производители», «Модели» и «Подмодели». (Любой из них может быть правильным, но они должны совпадать, чтобы вы читали и записывали одни и те же ключи!)

Наконец, вы используете один и тот же экземпляр EngineProperties каждый раз, когда вызываете saveData, или каждый раз создаете новый объект? Если вы не используете один и тот же объект, то iVars будет сбрасываться до нуля каждый раз, когда вы его вызываете.

person lnafziger    schedule 05.04.2012
comment
Я внес ваши изменения, но у меня все та же проблема. Вот что происходит, когда я регистрирую переменную 3 сразу после тех, если для каждого вызова. check ---› 245442 (null) (null) check ---› (null) 140211 (null) check ---› (null) (null) 9276 - person C.Johns; 05.04.2012
comment
каждый раз, когда я вызываю saveData, все мои переменные, которые я установил в своем первом методе, очищаются. Я думаю, может быть, я должен установить другие переменные со старыми значениями в каждом из этих операторов if. - person C.Johns; 05.04.2012
comment
См. Две другие проблемы, которые я рассматриваю, в нижней части моего обновленного ответа. - person lnafziger; 05.04.2012
comment
О да... Я определенно не использую один и тот же экземпляр... поскольку к классу, который я использую для вызова этого, обращаются несколько раз, и каждый раз он создает новый экземпляр! блин! что я должен сделать, чтобы исправить это? - person C.Johns; 05.04.2012
comment
Либо создайте один экземпляр и сохраните ссылку на него, чтобы использовать один и тот же экземпляр для всех своих вызовов (наиболее эффективно), либо читайте plist каждый раз перед его сохранением, чтобы получить начальные значения, а затем замените одно значение в словарь, который меняется. - person lnafziger; 05.04.2012
comment
Да, я понимаю. Я как раз собираюсь попытаться выяснить, как это сделать. Вскоре я отмечу ваш ответ. - person C.Johns; 10.04.2012

Прежде всего, когда вы звоните

- (void) saveData:(NSString *)methodName signature:(NSString *)pSignature Version:(NSNumber *)pVersion request:(NSNumber *)rNumber dataVersion:(NSNumber *)dvReturned cacheValue:(NSNumber *)cValue;

См. это для сравнения строкового значения

 //This opens up and reads the current plist ready to be used
-(void) readPlistData
{
    // Data.plist code
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"EngineProperties.plist"];

    // check to see if Data.plist exists in documents
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
    {
        // if not in documents, get property list from main bundle
        plistPath = [[NSBundle mainBundle] pathForResource:@"EngineProperties" ofType:@"plist"];
    }

    // read property list into memory as an NSData object
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSString *errorDesc = nil;
    NSPropertyListFormat format;
    // convert static property liost into dictionary object
    NSDictionary *tempRoot = (NSMutableDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
    man = [cacheValue objectForKey:@"Man"];
    mod = [cacheValue objectForKey:@"Mod"];
    sub = [cacheValue objectForKey:@"SubMod"];
    if (tempRoot && [tempRoot count]){
         // assign values
        self.signature = [tempRoot objectForKey:@"Signature"];
        self.version = [tempRoot objectForKey:@"Version"];
        self.request = [tempRoot objectForKey:@"Request"];
        self.dataVersion = [tempRoot objectForKey:@"Data Version"];
        cacheValue = [tempRoot objectForKey:@"Cache Value"];
    }

}


- (void) saveData:(NSString *)methodName signature:(NSString *)pSignature Version:(NSNumber *)pVersion request:(NSNumber *)rNumber dataVersion:(NSNumber *)dvReturned cacheValue:(NSNumber *)cValue
{
    // get paths from root direcory
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    // get documents path
    NSString *documentsPath = [paths objectAtIndex:0];
    // get the path to our Data/plist file
    NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"EngineProperties.plist"];

    // set the variables to the values in the text fields
    self.signature = pSignature;
    self.version = pVersion;
    self.request = rNumber;
    self.dataVersion = dvReturned;

    //do some if statment stuff here to put the cache in the right place or what have you.
    if (methodName isEqualToString:@"manufacturers") {
        self.man = cValue; 
    } else if (methodName isEqualToString:@"models") {
        self.mod = cValue;
    } else if (methodName isEqualToString:@"subMod") {
        self.sub = cValue;
    }

    self.cacheValue = [NSDictionary dictionaryWithObjectsAndKeys:
                   man, @"Manufacturers",
                   mod, @"Models",
                   sub, @"SubModels", nil];


    NSDictionary *plistDict = [NSDictionary dictionaryWithObjectsAndKeys:
                           signature, @"Signature",
                           version, @"Version",
                           request, @"Request",
                           dataVersion, @"Data Version",
                           cacheValue, @"Cache Value", nil];



    NSString *error = nil;
    // create NSData from dictionary
    NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

    // check is plistData exists
    if(plistData) {
        // write plistData to our Data.plist file
        [plistData writeToFile:plistPath atomically:YES];

        NSString *myString = [[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding];
       //        NSLog(@"%@", myString);
    } else {
           NSLog(@"Error in saveData: %@", error);
          //  [error release];
    }
}
@end
person Praveen-K    schedule 05.04.2012
comment
спасибо, я только что попытался реализовать его, и я получаю сообщение об ошибке с оператором if, где я передаю cValue переменным. Ожидается ']' разве они не должны иметь квадратные скобки? - person C.Johns; 05.04.2012
comment
Ну, я не думаю, что это должно быть проблемой, я только что проверил :(NSNumber *)cValue ; в определении метода «сохранить», поэтому я просто удалил точку с запятой в конце и отредактировал отвечать. Возможно, вы пропустили открытие и закрытие ']'. покажи мне линии. - person Praveen-K; 05.04.2012