views:

558

answers:

4

I'm using an NSRange (a struct) and initializing it like this:

@interface MyViewController : UIViewController
{
    NSRange currentRange;
}

NSRange has a location and length field.

How can I check to see if the struct has been initialized with a value? I tried:

if (myRange.length == nil)

but the compiler complained about comparing a pointer to an integer. Thanks.

A: 

You can't. If it's not initialized, it will have random values, or be initialized to zero, depending on the compiler, so there's no safe way to check.

Zydeco
It has to be initialized to 0, according to http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-TPXREF116
newacct
All instance variables are zeroed. But nevertheless you're right about not being able to check if the range is initialized, since {0, 0} is a valid NSRange.
Nikolai Ruhe
Why was this downvoted? The only way to check if it has been initialized is to add some additional construct to track that.
Toon Van Acker
I downvoted it because of the statement that initialization is depending on the compiler. This is wrong. I agree that you've got to use another way to track initialization.
Nikolai Ruhe
+4  A: 

nil is a pointer, but length is an integer, hence the compiler warning. You could compare length to 0, but then that's a legitimate value for a length in an NSRange. If I needed to have a "not yet initialised" value for currentRange, I'd choose to set it to:

{ .location = NSNotFound, .length = 0 }

in -init. That of course supposes that the range could never assume that value in the course of operations. If the range can really take on any of the values in its domain, then you can't use any of them as the placeholder for "not yet initialised".

You could choose to store a pointer to the range which is NULL until the range gets set. Another option would be to use the State pattern to distinguish between the states before and after the range gets set. Another is to design the class and its interface contract such that the range only ever gets used after it's been set.

Graham Lee
A: 

You have basically two options: either initialize the struct explicitly (the suggestion to intialize location to NSNotFound is a good one), or make it a pointer. But then you'll be managing heap memory for this, which is likely more than you bargained for.

Philosophically, doing any sort of comparison before initialization is begging for trouble. Even if this was a pointer, I'd still (personally) explicitly initialize it to nil. Is there some reason you don't have a bite at the apple during the -init method for MyViewController?

peterb
A: 

One potential solution to this is to store somewhere a cannonical initialized instance of that structure and compare against it. You still have the issue that you really aren't supposed to be doing anything with uninitialized memory except initializing it.

Clay