问题
I'm attempting to define an extremely simple utility method that will save me from having to use a calculator to define RGB values as percentages. When I look into Apple's sample code called "QuartzCache", in the DrawView.m file, line 96, I see this:
float whiteColor[4] = {1, 1, 1, 1};
However, when I attempt to created a method like the following, the compiler hates me. A half-hour of intensive Googling has not produced any help.
+(float[])percentagesRGBArray:(float[])rgbArray{
float red = rgbArray[0];
float green = rgbArray[1];
float blue = rgbArray[2];
float alpha = rgbArray[3];
red = red/255;
green = green/255;
blue = blue/255;
alpha = alpha;
float percentagesRGBArray[4] = {red, green, blue, alpha};
return percentagesRGBArray;
}
What is the proper way to define such a method? What am I doing wrong here?
回答1:
Define a struct
that contains all of the components, or wrap up each individual component in an NSNumber
. Alternatively, use an NSColor
instance to contain your colour components.
struct
way:typedef struct { float red; float green; float blue; float alpha; } MyColor; - (MyColor) percentagesRGBArray:(MyColor) incoming { MyColor result; result.red = incoming.red / 255; result.green = incoming.green / 255; result.blue = incoming.blue / 255; result.alpha = incoming.alpha; return result; }
NSNumber
way:- (NSArray *) percentagesRGBArray:(float[]) rgbArray { NSNumber *red = [NSNumber numberWithFloat:rgbArray[0] / 255]; NSNumber *green = [NSNumber numberWithFloat:rgbArray[1] / 255]; NSNumber *blue = [NSNumber numberWithFloat:rgbArray[2] / 255]; NSNumber *alpha = [NSNumber numberWithFloat:rgbArray[3]]; return [NSArray arrayWithObjects:red, green, blue, alpha, nil]; }
NSColor
way:- (NSColor *) percentagesRGBArray:(float[]) rgbArray { CGFloat red = rgbArray[0] / 255; CGFloat green = rgbArray[1] / 255; CGFloat blue = rgbArray[2] / 255; CGFloat alpha = rgbArray[3]; return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha]; }
回答2:
Normally, you would use Cocoa's NSColor
class to handle this sort of thing, but it looks like you are doing something a little more low-level.
In that case, I would do the following:
typedef struct
{
float red;
float green;
float blue;
float alpha;
}
RGBAData;
RGBAData ConvertRGBAToPercentages(const RGBAData source)
{
RGBAData percentages;
percentages.red = source.red/255;
percentages.green = source.green/255;
percentages.blue = source.blue/255;
percentages.alpha = source.alpha/255;
return percentages;
}
To be used as follows:
RGBAData original = { 0xFF, 0xFF, 0x00, 0x80 }; // 50% transparent yellow
RGBAData percents = ConvertRGBAToPercentages(original);
回答3:
Both e.James and dreamlax's answers give good approaches for doing this. But to answer what was wrong with your original code:
Basically, it has to do with how C arrays work. An array is essentially equivalent to a pointer to its first element. In fact, when you pass an array to a function, it decays into a pointer. You're still allowed to name the argument float myArray[4]
(you have to declare the number of elements) just to make it clear that the pointer is supposed to be to an array of 4 elements — but you're still getting a pointer. Now consider the return value. What are you returning? We already established that you can't return an array by value, because it decays into a pointer. But even if you change the return type to be a pointer, it still won't work, because the array will have gone out of scope once the function returns. In order to return an array, you have to malloc the memory, and then you're responsible for freeing it later.
This is why you should avoid working with C arrays when at all possible. They're really low-level and fiddly. Even when you do use them, it's usually a good idea to hide them behind an API that takes care of the low-level details for you.
回答4:
I think i'm late) but i have just found this thread.
the C way to do this is to create an array before invoking a function;
+(void) percentagesRGBArray:(float[])inArray toArray:(float*)outArray {
...
}
float array1[4];
float array2[4];
[MyClass percentagesRGBArray:array1 toArray:array2];
来源:https://stackoverflow.com/questions/2375088/objective-c-method-parameters-problem