Reading NSDictionary Keys from property lists

14,845

Solution 1

Try using [key isEqualToString: rowString] instead of comparing key and rowString directly using ==. I think == compares the object's pointer values, which will not be equal even if the strings match.

Also - just as an aside, you don't need to initialize URLforAll before setting it. When you set it equal to [dict objectForKey:@"URL"] you lose the pointer to the object you already created and it will be leaked. Instead, just say NSString *URLforAll = nil; or create a new string and autorelease it so that the object will be automatically cleaned up:

NSString * URLforAll = [[[NSString alloc] init] autorelease];

Solution 2

Further, in your code:

NSString *URLforAll = [[NSString alloc] init];

This never makes senses. Here are some issues:

  • You allocated an object which you then overwrite indiscrimanently with URLforAll = [dict objectForKey:@"URL"];. So you would need to release it before overwriting it.
  • It is allocated (ie, at the end of the loop, you "own" it and will have to release it. But [dict objectForKey:@"URL"] returns an object which you don't own. So at the end of the loop, you don't know whether you own URLforAll or not.
  • And finally, [[NSString alloc] init] never makes sense because you should just use @"", which returns a constant, empty, NSString which is impervious to retain/release/autorelease issues.

Dealing also with the isEqualToString issue, but ignoring amrox's much better solution, the code would be:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"];
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSString *URLforAll = @"";
for (id key in rootDict) {
        if ( [key isEqualToString:rowString] ) {
                NSDictionary *dict = [rootDict objectForKey:key];
                URLforAll = [dict objectForKey:@"URL"];
        }
}
[[URLforAll retain] autorelease];
[rootDict release];

Note that objectForKey may well return an internal reference to the object which will become invalid when you release the dictionary, hence the need for retaining the object if you want to keep it around longer than the life of the dictionary.

amrox's use of:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"];
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"];
[[URLString retain] autorelease];
[rootDict release];
if ( !URLString ) {
    URLString = @"";
}

is a better solution, but you should undertand what is wrong with your original solution as well.

Solution 3

You also don't need to loop through the dictionary. Just ask it for the data you want.

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"];
NSDictionary *rootDict = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
NNSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"];

// do something or return  URLString...
Share:
14,845
valiantb
Author by

valiantb

Updated on June 05, 2022

Comments

  • valiantb
    valiantb almost 2 years

    in my project i'm using a propertyList for maintaining data. the plist file is named "DataBase.plist". the Root for DataBase.plist is a dictionary which contains 5 dictionaries as child items... now the sub Dictionary contains 4 strings out of which one is always a webaddress with key "URL" (Without the quotes).... i'm running the following code to extract the value for this URL key but it is not working out..

    NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"];
    NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path];
    NSString *URLforAll = [[NSString alloc] init];
    for (id key in rootDict)
    {
        if(key == rowString)
        {
            NSDictionary *dict = [rootDict objectForKey:key];
            URLforAll = [dict objectForKey:@"URL"];
        }
    }
    

    the rowstring is a string whose value is the same as the text in the selected cell (i've tested it , it is accurate). PLease help me out if you can.... i'll be thankful