Simple Question from a Cocoa newbie

Discussion in 'Mac Programming' started by CMT, Mar 30, 2010.

  1. CMT macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #1
    Hello,

    I've been trying to get the Hex value of an NSColor. I found an Apple technical Q&A for this, but can't make it work. I receive a EXC_BAD_ACCESS when calling the method.

    The code from the class:

    Code:
    @interface NSColor (NSColorHexadecimalValue)
    
    -(NSString *)hexadecimalValueOfAnNSColor;
    
    @end
    
    @implementation NSColor (NSColorHexadecimalValue)
    
    -(NSString *)hexadecimalValueOfAnNSColor {
    	
    	float redFloatValue, greenFloatValue, blueFloatValue;
    	int redIntValue, greenIntValue, blueIntValue;
    	NSString *redHexValue, *greenHexValue, *blueHexValue;
    	
    	//Convert the NSColor to the RGB color space before we can access its components
    	NSColor *convertedColor=[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
    	
    	if(convertedColor)
    	{
    		// Get the red, green, and blue components of the color
    		[convertedColor getRed:&redFloatValue green:&greenFloatValue blue:&blueFloatValue alpha:NULL];
    		
    		// Convert the components to numbers (unsigned decimal integer) between 0 and 255
    		redIntValue=redFloatValue*255.99999f;
    		greenIntValue=greenFloatValue*255.99999f;
    		blueIntValue=blueFloatValue*255.99999f;
    		
    		// Convert the numbers to hex strings
    		redHexValue=[NSString stringWithFormat:@"%02x", redIntValue];
    		greenHexValue=[NSString stringWithFormat:@"%02x", greenIntValue];
    		blueHexValue=[NSString stringWithFormat:@"%02x", blueIntValue];
    		
    		// Concatenate the red, green, and blue components' hex strings together with a "#"
    		return [NSString stringWithFormat:@"#%@%@%@", redHexValue, greenHexValue, blueHexValue];
    	}
    	return nil;
    }
    @end
    And then the main:

    Code:
    #import <Cocoa/Cocoa.h>
    #import "HexConvert.h"
    
    int main(int argc, char *argv[])
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	
    	NSColor *blue = [NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:1.0];
    	
    	NSString *hexName = [blue hexadecimalValueOfAnNSColor];
    	
    	NSLog(hexName);
    	
    	[pool release];
    	return NSApplicationMain(argc,  (const char **) argv);
    }
    Does someone knows what's going on?

    Thank you a lot!
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    When you run it in the debugger on exactly which line does it crash. If you have not run it through the debugger you should do this first of all.
     
  3. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #3
    Crashes on

    NSString *hexName = [blue hexadecimalValueOfAnNSColor];

    [Switching to process 529]
    Running…
    Program received signal: “EXC_BAD_ACCESS”.
    sharedlibrary apply-load-rules all
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: check_safe_call: could not restore current frame

    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: check_safe_call: could not restore current frame

    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    kill
    warning: Unable to restore previously selected frame.
    Current language: auto; currently objective-c
    quit
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Is that a Debug build? Anyway have you imported the file with your category in it?
     
  5. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #5
    Yes, a imported (#import "HexConvert.h")

    Pretty strange bug. The complete debbuger:


    [Session started at 2010-03-30 12:51:37 -0300.]
    GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys001
    Loading program into debugger…
    Program loaded.
    run
    [Switching to process 891]
    Running…
    Program received signal: “EXC_BAD_ACCESS”.
    sharedlibrary apply-load-rules all
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: check_safe_call: could not restore current frame

    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: check_safe_call: could not restore current frame

    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    warning: Unable to restore previously selected frame.
    kill
    warning: Unable to restore previously selected frame.
    Current language: auto; currently objective-c
    quit

    The Debugger has exited with status 0.(gdb)
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Can you post details of exactly what is in which file? Are both the @interface and @implementation of the category in the .h file? If so that's wrong: move the @implementation to a .m file.
     
  7. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #7
    No they are separated in HexUtility.h and .m . In .h the @interface and @implementation in .m .

    This is driving me crazy
     
  8. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    Can you test if blue is nil after creating? I'm wondering if there is an issue with using NSColor/AppKit classes in a command line app. Especially as you have not created an instance of NSApplication which, I think, initialises AppKit in some way.

    I note that AppKit, in general, is not daemon-safe and required a connection to the GUI.

    See the overview of NSApplication for details of how you should be creating an NSApplication object...
     
  9. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #9
    Hmm ok I'll search about it.

    By the way, here is an Xcode project with files.
     

    Attached Files:

  10. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #10
    This is not an command line app…
     
  11. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #11
    I added:

    Code:
    if (blue == nil) {
    	NSLog(@"Yes it is nil");
    }
    else {
    	NSLog(@"No it is not nil");
    }
    and debugger returned 'No it is not nil' :)
     
  12. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #12
    Well your main above certainly is: it does not initialise the app kit or display any GUI...

    I'm not on a Mac right now so I can't look at the project. Maybe someone else who is can...
     
  13. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #13
    Take note of what your warnings tell you when you compile. You should get a warning about incompatible pointer types. What does the getRed:green:blue:alpha: method expect?

    This should be a one word modification.
     
  14. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #14
    Ouch!

    from the documentation:

    Declaration: - (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha
     
  15. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #15
    The forum messed up a little.

    Code:
    - (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha
    Ok, I changed from variables:

    Code:
    float redFloatValue, greenFloatValue, blueFloatValue;
    To:

    Code:
    CGFloat *redFloatValue, greenFloatValue, blueFloatValue;
    And now I get an error on
    Code:
    redIntValue=redFloatValue*255.99999f;
    .

    "Invalid operands to binary *"
     
  16. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #16
    It's probably a case that the example code you used was out of date. What you put would have been fine a few years ago. For almost all cases you shouldn't be using basic C type declarations (int, float, unsigned), but the 64 bit safe versions (NSInteger, CGFloat, NSUInteger) which make sure the code works fine in 32 and 64 bit environments. This includes your declaration of int.
     
  17. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #17
    Take off the * after CGFloat. It's not an object.
     
  18. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
  19. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #19
    :D

    Works now, perfectly. It would be helpful if Apple corrects that.

    Thanks robbieduncan and JoshDC
     
  20. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #20
    Help them to help you (and others).

    There is a small feedback box at the bottom of the QA1576 webpage:
    Did this document help you? Yes It's good, but... Not helpful...
    Click the link "It's good but..." and tell them exactly what problem you had.
     
  21. CMT thread starter macrumors member

    CMT

    Joined:
    Aug 24, 2009
    #21
    I did this right after the solution was found. :apple:

    Thanks chown33
     

Share This Page