views:

68

answers:

2

In my iPhone app, I have a appSettings.plist. This allows me, but also others to simply change some parameters. One of the parameters is the predominant color of the app. The .plist looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
 <key>Red</key>
 <integer>255</integer>
 <key>Green</key>
 <integer>123</integer>
 <key>Blue</key>
 <integer>124</integer>
 <key>compositeRGB</key>
</dict>
</plist>

In my code, I read this file, and try to make a UIColor out of these three numbers. I have to admit that I don't know too much about CGFLoats, and I suspect that that is the cause of my trouble. This is what I do:

-(void)readAppSettings
{
 NSString *path = [[NSBundle mainBundle] bundlePath];
 NSString *finalPath = [path stringByAppendingPathComponent:@"appSettings.plist"];
 NSDictionary *plistDictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];

 unsigned int RedComponent = [[plistDictionary objectForKey:@"Red"]intValue];
 unsigned int GreenComponent = [[plistDictionary objectForKey:@"Green"]intValue];
 unsigned int BlueComponent = [[plistDictionary objectForKey:@"Blue"]intValue];

 appColor = [UIColor colorWithRed: ((float) RedComponent / 255.0f) 
          green: ((float) GreenComponent / 255.0f) 
        blue:((float) BlueComponent / 255.0f)
          alpha:1.0f];
}

whenever I try to use appColor as a UIColor, my app crashes, with the following error:

'-[__NSCFArray CGColor]: unrecognized selector sent to instance 0x7b0ab20'

Could somebody explain to me what I'm doing wrong. You don't have to be polite.
+2  A: 

you should retain appColor and release it in your dealloc method. You're dereferencing a bad pointer most likely

The Memory Management Programming Guide can be a good reference

cobbal
Thank you so much. That did the trick. I was very much struggling with the CGFLoat, that I overlooked such a basic thing.
Sjakelien
I was also quite puzzled by "-[__NSCFArray CGColor]:" in the error message, but I shouldn't have paid attention to that I guess.
Sjakelien
@Sjakelien memory errors like that are notoriously hard to track down. One helpful way to find them is to run with zombies enabled.
cobbal
Interesting: I enabled the Zombies, and the code runs fine without retaining.Is that what it does? Isn't that kind of dangerous? Is it just for checking if there is something wrong with memory management, or does it actually FIX things? That would be really great for sloppy people like me...
Sjakelien
Or maybe I'm seeing just things. I'm going to sleep.
Sjakelien
@Sjakelien It should only be used for debugging. Basically it means that nothing is released (things will throw an exception if they receive any messages after they've been "deallocated"). Never distribute code that has zombies, it will leak everything by definition.
cobbal
A: 

Works for me ;)

#import <UIKit/UIKit.h>

@interface deleteColorAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UINavigationController *navigationController;
    UIColor *appColor;
}

@property (nonatomic, retain) UIColor *appColor;

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

-(UIColor*)readAppSettings;

@end


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.
    // Add the navigation controller's view to the window and display.

    [self readAppSettings];
    UILabel *label = [[UILabel alloc] init];
    label.textColor = appColor;
    label.text = @"This is a test";
    label.frame = CGRectMake(100, 100, 100, 40);

    [navigationController.view addSubview:label];
    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];
    [label release];
    return YES;
}

- (void)applicationWillTerminate:(UIApplication *)application {

    // Save data if appropriate.


}

-(UIColor*)readAppSettings
{
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSString *finalPath = [path stringByAppendingPathComponent:@"appSettings.plist"];
    NSDictionary *plistDictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];

    float RedComponent = [[plistDictionary objectForKey:@"Red"]floatValue] / 255.0f ;
    float GreenComponent = [[plistDictionary objectForKey:@"Green"]floatValue] / 255.0f ;
    float BlueComponent = [[plistDictionary objectForKey:@"Blue"]floatValue] / 255.0f ;

    appColor = [UIColor colorWithRed:   RedComponent  
                               green:   GreenComponent 
                                blue:   BlueComponent 
                               alpha:   1.0f];
    return [appColor retain];
}



- (void)dealloc {
    [appColor release];
    [window release];
    [navigationController release];
    [super dealloc];
}
Jordan