NSDictionary class changing if held in external Si

2019-08-22 09:57发布

问题:

I am watching a somewhat cruel behaviour momentarily: I have a ViewController for building a View programmatically. For this purpose I have stored the names of the UILabels that will be displayed in a NSDictionary that is held in an external class which is a singleton. Unfortunately the NSDictionary is not accessible if I want to use the values in loadView. So I made some tests: The NSDictionary and its contents are availbale in init and the class is, of course, NSCFDictionary. If I have a look at it in loadView the class sometimes is NSCFDictionary and sometimes also CALayer or NSString?! I absolutely don't know what is happening??? This is the code I use:

- (id) init
{
    self = [super initWithNibName:nil bundle:nil];    
    if (self)
    {
        UITabBarItem *tbi = [self tabBarItem];
        [tbi setTitle:@"xxx"];
    }

    NSEnumerator *num = [[[ValueDispatcher dispatcher] labelDic] keyEnumerator];
    NSLog(@"Class(init): %@", [[[ValueDispatcher dispatcher] labelDic] class]);
    NSLog(@"No: %i", [[[ValueDispatcher dispatcher] labelDic] count]);
    for (id key in num)
    {
        NSLog(@"Key %@  Value  %@", key, [[[ValueDispatcher dispatcher] labelDic] valueForKey:key]);
    }

       return self;
    }  

- (void)loadView 
{
    NSLog(@"Class(loadview)1: %@", [[[ValueDispatcher dispatcher] labelDic] class]);
    NSLog(@"No: %i", [[[ValueDispatcher dispatcher] labelDic] count]);
    NSEnumerator *num = [[[ValueDispatcher dispatcher] labelDic] keyEnumerator];
    for (id key in num)
    {
        NSLog(@"Key34 %@  Value  %@", key, [[[ValueDispatcher dispatcher] labelDic] valueForKey:key]);
    }
...

At which point between init and loadView can or will a NSDictionary be changed? Btw, another info that might be important: If I use the above code and the NSDictionary is filled by an external service everything works fine. But if I fill the NSDictionary from a stored plist during startup it fails and I watch the described behaviour...

回答1:

If I have a look at it in loadView the class sometimes is NSCFDictionary and sometimes also CALayer or NSString?

this (typically) means you have a reference count issue or you have not unregistered your observers correctly -- assuming you never set the dictionary. run instruments with zombies enabled.

At which point between init and loadView can or will a NSDictionary be changed?

a lot can happen in that time beyond the code you posted.



回答2:

You'll need to retain that dictionary for as long your singleton needs it.

If you're using ARC, just make sure that ivar and/ or property are strong.

If you aren't using ARC, and you have a property setter to manage this for you, make sure you are actually using that setter.

And if no ARC, and you're setting your ivar directly, just make sure to retain the dictionary (and release the old one, if any)