tags:

views:

1286

answers:

6

In the following code, I'm creating a category on UIColor to create a random color. However, from this code, I would have thought that the 'if' conditional would be true every time the method is run, instead of just the first time.

I think I'm not really understanding static variables correctly. Does a static variable only get set once, and then the second time the method is run, that line is just ignored? (so seeded would forever be YES after the first run)?

@interface UIColor(Random)
+(UIColor *)randomColor
{
    static BOOL seeded = NO;
    if (!seeded) 
    {
     seeded = YES;
     srandom(time(NULL));
    }
    CGFloat red = (CGFloat)random()/(CGFloat)RAND_MAX;
    CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX;
    CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX;
    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
}
+5  A: 

You are correct that the static variable only is set once.

the code

static BOOL seeded = NO;

is not equivalent to

static BOOL seeded;
seeded = NO;

the second one would always evaluate to NO, while the first one will evaluate to NO until set differently.

cobbal
+3  A: 

Here static means that the current value of seeded is not lost from one call of the method to the next. The assignment on the declaration line defines only the first value of seeded.

Yes, seeded will forever be YES after the first run.

mouviciel
A: 

A static variable maintains its value when control leaves the scope of the function. So seeded will be set to whatever value it last had. In your case, you initialize seeded with NO and then set it to YES. So, to answer your question, yes: seeded will always be YES after the first time this method is called.

Jason Coco
The phrase "outside the scope of" might be reworded to "when control leaves the scope of" since the variable isn't available outside the scope of the function.
NVRAM
Yes, this is true...
Jason Coco
A: 

hey u can change values of static variables as many times you want. The reason your if statement is true only once is because you have declared and assigned no in the same statement. Try seperating the two to see the if statement true on every run

Raj
+1  A: 

As others have said, static local variables are initialized to a specific value on creation, and retain that value until changed. Static global variables, on the other hand, mean it is local to the file scope -- that is, unaccessable outside of the current source file.

A little history/low level detail can be found at http://en.wikipedia.org/wiki/Block_Started_by_Symbol

Brian Mitchell
+1  A: 

Static variables are not allocated on the stack like your red, green and blue variables are in this example. They:

  1. Are allocated in memory at a single, immutable location,
  2. Consume memory even if the containing function is never called,
  3. Can cause problems when the function is used in multiple threads -- although your example has a very small likelihood of a race condition, and
  4. Are assigned once only; offhand I don't recall if it's on the first time the function is called or on when the code is loaded (the latter, I think).

It might help you to think of it as if the compiler moves the declaration (with assignment) outside the function/class scope but access is restricted to within the function.

NVRAM