无法更改/替换NSDictionary键值IOS

时间:2012-10-02 17:13:20

标签: objective-c ios plist nsdictionary

我正在从Dropbox下载文件修订版状态,基本上我将Dropbox中下载的修订版号与本地plist中的版本号进行比较。

在比较它们之后,我想用Dropbox的修订号更改本地修订号。但它无法正常工作,我将失去理智。

我放了一些标志和NSlogs似乎它取代了值但是在我调用相同的函数或再次启动应用程序后,我发现该值未被替换。它一次又一次地提供相同的输出

    NSString* revisionLocal = [dicInner objectForKey:@"revision"];
    NSString* statusLocal = [dicInner objectForKey:@"status"];

    NSLog(@"revision  value before %@",revisionLocal);
    NSLog(@"status value before %@",statusLocal);

   //If revision has changed on dropbox, flag it as outdated on the local revision
                        if(![revisionLocal isEqualToString: dropBoxRevision] ){
                            [dicInner setValue:@"outdated" forKey:@"status"];
                            //But the revision is the latest
                            [dicInner setValue:dropBoxRevision forKey:@"revision"];
                            //[dicInner setValue:@"outdated" forKey:@"revision"];

                            NSLog(@"revision value %@",[dicInner objectForKey:@"revision"]);
                            NSLog(@"status value %@",[dicInner objectForKey:@"status"]);

所以这给了我输出:

revision  value before 4309efbbb7
status value before updated
revision value 4409efbbb7
status value outdated

完整的代码是:

- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {

    //get the local revision
    NSDictionary * localRevisionDic = [FileUtils readPlistIntoDictionary:@"revision.plist"];

    NSString *fileRevString = [NSString alloc];
    //get the revision from Dropbox
    //NSString * dropboxRevision;
    if (metadata.isDirectory) { 
        NSLog(@"Folder '%@' contains:", metadata.path);
        for (DBMetadata *file in metadata.contents) {

            NSLog(@"\t%@", file.filename);
            //NSLog(@"\t%@", file.lastModifiedDate);
            NSLog(@"\t%@", file.rev ); 

            //Assign dropbox revision for this file
            //dropboxRevision = file.rev;
            //if no local revision.plist, entry will be added. Hence init here
            if (localRevisionDic==nil){
                localRevisionDic = [[NSMutableDictionary alloc]init];

            }
            //Otherwise go through each from dropbox and campare with local

            //From Dropbox
            NSString * dropBoxFileName = file.filename;
            NSString * dropBoxRevision = file.rev;

            fileRevString = file.rev;

            //if no local revision.plist entry is added for all other files
            //with status need_downloaded, and no revision
            if ([localRevisionDic count]==0){

                //Creating revision dictionary entry for agenda.plist
                NSDictionary * localRevisionDicDic = [[NSMutableDictionary alloc]init];
                //when agenda.plist revision entry is added update the revision while leaving status as "new" before downloading
                //will be updated accordingly if download fails
                [localRevisionDicDic setValue:@"new" forKey:@"status"];
                //Status is new but the revision is the latest
                [localRevisionDicDic setValue:dropBoxRevision forKey:@"revision"];

                [localRevisionDic setValue:localRevisionDicDic forKey:dropBoxFileName];

            }else{//If there is local revision.plist compare and update accordingly
                NSDictionary * dicInner = [localRevisionDic objectForKey:dropBoxFileName];
                //File name Found locally
                if (dicInner!=nil){
                    NSString* revisionLocal = [dicInner objectForKey:@"revision"];
                    NSString* statusLocal = [dicInner objectForKey:@"status"];

                    NSLog(@"revision  value before %@",revisionLocal);
                    NSLog(@"status value before %@",statusLocal);

                    //If revision has changed on dropbox, flag it as outdated on the local revision
                    if(![revisionLocal isEqualToString: dropBoxRevision] ){
                        [dicInner setValue:@"outdated" forKey:@"status"];
                        //But the revision is the latest
                        [dicInner setValue:dropBoxRevision forKey:@"revision"];
                        //[dicInner setValue:@"outdated" forKey:@"revision"];

                        NSLog(@"revision value %@",[dicInner objectForKey:@"revision"]);
                        NSLog(@"status value %@",[dicInner objectForKey:@"status"]);
                    }
                    }else{//File name not found locally newly added on dropbox

                        NSDictionary * localRevisionDicDic = [[NSMutableDictionary alloc]init];
                        //when agenda.plist revision entry is added update the revision while leaving status as "new" before downloading
                        //will be updated accordingly if download fails
                        [localRevisionDicDic setValue:@"new" forKey:@"status"];
                        //But the revision is the latest
                        [localRevisionDicDic setValue:dropBoxRevision forKey:@"revision"];

                        [localRevisionDic setValue:localRevisionDicDic forKey:dropBoxFileName];
                }
            }
        }
    }
    //At this point agendaRevisionDicTemp contains all the files in dropbox entered/updated.
    [[self agenda] setRevision:localRevisionDic];

    //*****The following block is needed to determine is new agenda is needed or not.
    BOOL newAgendaNeeded = false;

    NSMutableDictionary * agendaRevisionDicLocal = [localRevisionDic objectForKey:@"agenda.plist"];

    //NSString * localRevision = [agendaRevisionDicLocal objectForKey:@"revision"]; //what is this value?

    NSString * localStatus = [agendaRevisionDicLocal objectForKey:@"status"];
    NSLog(@"Local Status= %@",agendaRevisionDicLocal);


    if ([localStatus isEqualToString:@"new"] ||[localStatus isEqualToString:@"outdated"]){
        newAgendaNeeded = true;
        //when agenda.plist is added update the revision while leaving status as "new" before downloading
        //will be updated accordingly if download fails
        NSDictionary * agendaDic = [[[self agenda]revision] objectForKey:@"agenda.plist"];
        [agendaDic setValue:@"updated" forKey:@"status"];
        NSLog(@"agendaDic where update %@",agendaDic);

    }
    //*****The above block is needed to determine is new agenda is needed or not.

    //If new agenda is needed download
    if (newAgendaNeeded){
        //Download agenda.plist
        NSString *documentsDirectory = FileUtils.getDocumentsDirectory;
        [[self restClient] loadFile:@"/agenda.plist" intoPath: [ NSString stringWithFormat:@"%@/%@",documentsDirectory,@"agenda.plist"] ];

    } else{//Else display the scene

        [self populateSceneFromAgenda];

    }

    [restOfView reloadData];
    // Add at start of requestFinished AND requestFailed
    [MBProgressHUD hideHUDForView:self.view animated:YES];
}

任何想法如何替换该值?

2 个答案:

答案 0 :(得分:2)

您不尊重NSDictionary对象的不变性。您将localRevisionDic声明为NSDictionary *,但稍后可以为其指定NSMutableDictionary的值。 localRevisionDicDic声明为NSDictionary *,但初始化为NSMutableDictionary的值。应在编译时警告以下两项任务。在第
一行

[localRevisionDic setValue:localRevisionDicDic forKey:dropBoxFileName];

谁肯定知道localRevisionDic是可变的还是不可变的?
然后,再次声明dicInner为NSDictionary *,但稍后尝试setValue两次。首先制作字典的mutableCopy。

答案 1 :(得分:0)

我猜您的字典更改正确您的代码错误应该是您不将字典保存到您编辑的plist

事实上,该方法[[self agenda] setRevision:localRevisionDic];

存在一些问题

尝试在[[self agenda] setRevision:localRevisionDic];

中添加以下代码
//write dictionary to plist 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"revision.plist"];
    // write plist to disk
    [localRevisionDic writeToFile:path atomically:YES];

    // read it back in with different dictionary variable
    NSMutableDictionary *savedStock = [NSMutableDictionary dictionaryWithContentsOfFile:path];
    if( savedStock==nil ){
        NSLog(@"failed to retrieve dictionary from disk");
    }