Does declaring a variable outside a loop in Objective-C have any optimising effect? - objective-c

I have acquired the habit of declaring reused variables outside loops from having worked in Other Languages, like so:
NSString *lcword;
for( NSString *word in tokens )
{
lcword = [ word lowercaseString ];
...
}
Is it reasonable to do this in Objective-C also, or is the compiler smart enough to make it unnecessary?

There's no benefit in Objective-C that I know of. AFAIK every modern Objective-C compiler allocates the stack space for local variables at the beginning of the function or method. Scoping the variable to the loop just prevents you from using the name outside the loop and prevents the compiler from reusing the stack space if it wants to.
See also: Is there any overhead to declaring a variable within a loop? (C++) (It's about a different language, so I wouldn't mark it as a dupe, but the compiler techniques at work are very similar)

If you can reuse a variable then do it. No need to declare a new one each iteration if it's not needed.

Related

Objective-C Declaring Variables Within Loop -- Performance

I've been teaching myself Objective-C via some lectures from iTunes U.
I like the course, but the professor routinely writes code like this:
while (index < [self.textToAnalyze length]) {
NSRange range;
id value = [self.textToAnalyze attribute:attributeName atIndex:index effectiveRange:&range];
....
}
I have mostly worked in C and C++, and there are a couple of things about this code that seem glaringly wrong to me from a performance / style perspective.
The code declares two variables (of type NSRange and id) inside the loop. A naive compiler would reserve space for each of these types of variables at each iteration through the loop.
The code calls the length selector ([self.textToAnalyze length]) in the loop condition. As the programmer, I know that the length of the textToAnalyze property does not change while the loop is iterating. However, I'm not convinced that the compiler will know this. Won't this code call the length selector every single iteration of the loop?
I know that compilers can be very crafty, but I think it is bad code to declare variables within a loop and call functions within the loop conditions. It could affect the performance, and in my mind, it is certainly poor style.
However, I am new to Objective-C, so here is my question:
Is this bad code, or are these Objective-C idioms that are fine to use?
The answer is: it depends.
For variables in loops, moving them out of the loop might improve performance of the loop, but now you've changed the scope and effected performance in another way. Which is better is definitely going to be situation-based.
But, as far as I'm concerned, a variable with a scope any wider than necessary is bad practice. Variables with unnecessarily wide scope and lead to user error. The amount of performance improvement you might get here is not worth ANY amount of debugging that could've been avoided with a narrower variable scope.
As for calling methods in loop conditions, again, this depends.
I'm quite certain that the length method of NSString is quite optimized. The length of a string is not analyzed every time length is called, and especially not so for NSString (as opposed to NSMutableString. If we're talking about an immutable string, calling length is simply returning an NSInteger value stored within the class and performance will be fine.
If, however, we're talking about an immutable string, we need to call length every time if it's important that we're only within the length of the string.
It's a mutable string. Even if this loop doesn't modify the string, it can be modified else where by anyone that has a reference to it. If you're concerned about performance, make an immutable copy of the string and use that immutable copy in the loop.
[myString length]
According to this answer, for both mutable and immutable versions, there is a variable within the class that stores the string's length. For immutable strings, this is calculated when the string is created and never changed. For mutable strings, this variable is calculated and set each time the string changes. At the end of the day, when you call string, it's purely returning the value of an internally stored int value in the class and will not be any slower than storing this length in a separate variable before the loop and comparing against this.
I think it is theoretically possible for some loop conditions to be cached, but in practice that doesn't seem to happen — the length method will be called every time through the loop.
Does that make this bad code? Not necessarily. The overhead of a function call is not that huge. If this loop needs to be tight, then yes, caching the string's length is a great idea. But in many cases, it just doesn't make any measurable difference, so less code is better code.
As for declaring variables in a loop, that isn't problematic. There are two mainstream Objective-C compilers in existence, and neither has any trouble compiling that to efficient code. I doubt even POC has trouble with that. Muddling your variables' scope just to please a hypothetical awful compiler isn't good code — it's premature optimization. (Incidentally, the same holds true for C++ too.)

What is the -> operator doing in -copyWithZone:? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arrow operator (->) usage in C
Dot (“.”) operator and arrow (“->”) operator use in C vs. Objective-C
I'm a newbie looking at a freeware/open-source program last updated in 2008, and I don't recognize the -> in the following notation:
- (id)copyWithZone:(NSZone *)zone
{
GFIPGeniusItem * newItem = [[[self class] allocWithZone:zone] init];
newItem->_stringValue = [_stringValue copy];
newItem->_imageURL = [_imageURL copy];
newItem->_webResourceURL = [_webResourceURL copy];
newItem->_speakableStringValue = [_speakableStringValue copy];
newItem->_soundURL = [_soundURL copy];
return newItem;
}
I'm assuming it's allowing some sort of shortcut, but I'd love to specifically what it does.
It's a way to directly access an instance variable within an ObjC object from outside that object. (The syntax and -> is borrowed from C structs, behaving as if the reference were a pointer-to-structure).
This access mechanism is almost vestigial at this point, and very uncommonly seen in modern ObjC code, because good encapsulation requires the use of accessors and properties, not touching instance variables directly. It's legitimate in some very special cases, though, and this is one of them:
When copying an object, you want to get a resulting copy that matches exactly the state of the current self. The cleanest way of achieving this is often to set the copy's ivars explicitly, to prevent any side-effects that the init overloads or accessors might cause. It's "safe" because the code doing it is still located within the class that's in question, so if you needed to change or add ivars, you could update this code as well with the knowledge of anything else that might require.
Doing this from outside the class in question is bad form, and there's no good reason to do it.
In Objective-C you have some kind of two variable type accessors. The one everybody should know is the "." one (e.g. Class.variable). This type calls either the appropriate getter or setter.
Now, the other type - the one you asked for - is for in-class usage. Obviously, as the getter or setter gets called automatically with the "." notation you need a way to set the variable without a setter (calling the setter in the setter itself results in an endless loop). Therefore, this "->" notation is used -> simply, it is the direct-access mode.
Usually, Objective-C the variable name for both notations is the same but some prefer to have the in-class notation variable name beginning with "_". This is achieved by editing the #synthesize variable line to #synthesize variable = _variable.
That's a pointer indirection operator. a->b means the same thing as (*a).b (where the . is the structure member access operator, not Objective-C's property dot syntax).
When you say:
newItem->_stringValue
you're directly accessing the _stringValue instance variable of the object to which newItem points.
The -> operator is very common in C++, but not so much in Objective-C.
In Objective C, like in C++, the p->m notation is equivalent to (*p).m This is, the dereference of the pointer to the base type followed by a call to the corresponding method or property.
So in your case, using the other notation it would look like this:
(*newItem)._stringValue = [_stringValue copy];
(It's more common to use the -> operator)

Static variable in objective c

I am somewhat confused about memory allocation of static variable in objective C.
should we allocate memory for static variable using alloc:? and
initialize it usinginit:?
Is objective c static variable same as c static variable?
is it worth to apply retain on static variable?
There are a couple of things you need to take into account.
First, static C-like variables inside functions are technically fine. This should be:
- (void) f
{
static NSString* s = nil;
if (s == nil) {
s = [[NSString alloc] initWithString:#"Hello"];
}
}
The problem is that you will probably never be able to release, since s scope is only f function.
This is exactly like a C static variable inside a function.
There is also static usage to control visibility of a variable in a translation unit. So, if you want to only allow some variable to be accessed within file.c, just like C, you need to write in that file:
static NSString *s = [[NSString alloc] initWithString:#"Hello"];
Again, unless you write a specific method to release when you application ends, it will probably leak memory.
Finally, you can have "object oriented like" static behavior. You don't use static keyword here but as most object oriented languages, you can have class variables (in Java, C#, C++ and others, class variables are accomplished with the static keyword).
I only have answers to the first two of your questions — because I don't understand what you mean by your third one.
Let me start with question 2.:
Is objective c static variable same as c static variable?
Objective C (ObjC) is, basically, just plain-old-C (POC) — and a nifty dynamic runtime, that adds a lot of fancy.
This means that every C language qualifier (e.g. static) works in ObjC exactly like it would in POC.
So the answer to that question is: yes.
With that cleared, back to number one:
should we allocate memory for static variable using alloc:? and initialize it usinginit:?
The important thing about ObjC you need to always be aware of is, that there are no stack objects:
Every object you'll ever use lives on the heap.
From that follows that it is irrelevant in which scope (be it stack-local, static or global) you declare your object-type variables, in general, they will always be effectively alloc/inited.
There is one exception to these rules:
Blocks at least start out as stack variables — but those are funny creatures, anyway.
So, to answer this question: You actually don't have a choice!
Aside
if you're using statics for objects other than literal NSStrings — which might well be totally reasonable — consider wrapping them with a proper class-method, for sanity's sake.
This is a nice way of doing it:
+ (NSNumber *)theMagicNumber
{
static NSNumber *magicNumber;
static dispatch_once_t numberSemaphore;
dispatch_once( &numberSemaphore, ^{
magicNumber = [NSNumber numberWithInt:3]; // 1
[magicNumber retain]; // 2
} );
return magicNumber;
}
Notes:
As you probably know +[NSNumber numberWithInt:] returns an autoreleased object!
Since we want to hold on to this object, we need to retain it, as usual — or compile our code using ARC and get rid of lines like this, altogether!
I hope this example answers or at least helps you figuring out the answer to your last question.

static NSStrings in Objective-C

I frequently see a code snippet like this in class instance methods:
static NSString *myString = #"This is a string.";
I can't seem to figure out why this works. Is this simply the objc equivalent of a #define that's limited to the method's scope? I (think) I understand the static nature of the variable, but more specifically about NSStrings, why isn't it being alloc'd, init'd?
Thanks~
I think the question has two unrelated parts.
One is why isn't it being alloc'ed and init'ed. The answer is that when you write a Objective-C string literal of the #"foo" form, the Objective-C compiler will create an NSString instance for you.
The other question is what the static modifier does. It does the same that it does in a C function, ensuring that the myString variable is the same each time the method is used (even between different object instances).
A #define macro is something quite different: It's "programmatic cut and paste" of source code, executed before the code arrives at the compiler.
Just stumbled upon the very same static NSString declaration. I wondered how exactly this static magic works, so I read up a bit. I'm only gonna address the static part of your question.
According to K&R every variable in C has two basic attributes: type (e.g. float) and storage class (auto, register, static, extern, typedef).
The static storage class has two different effects depending on whether it's used:
inside of a block of code (e.g. inside of a function),
outside of all blocks (at the same level as a function).
A variable inside a block that doesn't have it's storage class declared is by default considered to be auto (i.e. it's local). It will get deleted as soon as the block exits. When you declare an automatic variable to be static it will keep it's value upon exit. That value will still be there when the block of code gets invoked again.
Global variables (declared at the same level as a function) are always static. Explicitly declaring a global variable (or a function) to be static limits its scope to just the single source code file. It won't be accessible from and it won't conflict with other source files. This is called internal linkage.
If you'd like to find out more then read up on internal and external linkage in C.
You don't see a call to alloc/init because the #"..." construct creates a constant string in memory (via the compiler).
In this context, static means that the variable cannot be accessed out of the file in which it is defined.
For the part of NSString alloc, init:
I think first, it can be thought as a convenience, but it is not equally the same for [[NSString alloc] init].
I found a useful link here. You can take a look at that
NSString and shortcuts
For the part of static and #define:
static instance in the class means you can access using any instance of the class. You can change the value of static. For the function, it means variable's value is preserved between function calls
#define is you put a macro constant to avoid magic number and string and define function macros. #define MAX_NUMBER 100. then you can use int a[MAX_MUMBER]. When the code is compiled, it will be copied and pasted to int a[100]
It's a special case init case for NSString which simply points the NSString pointer to an instance allocated and inited at startup (or maybe lazily, I'm not sure.) There is one one of these NSString instances created in this fashion for each unique #"" you use in your program.
Also I think this is true even if you don't use the static keyword. Furthermore I think all other NSStrings initialized with this string will point to the same instance (not a problem because they are immutable.)
It's not the same as a #define, because you actually have an NSString variable by creating the string with the = #"whatever" initialization. It seems more equivalent to c's const char* somestr = "blah blah blah".

self.variable and variable difference [duplicate]

This question already has answers here:
Difference between self.var and simply var
(3 answers)
Closed 8 years ago.
What is the difference between self.myVariable = obj; and myVariable = obj;, when I use #propery/#synthesize to create `myVariable?
It's important to note that dot-syntax is converted to a simple objc_msgSend call by the compiler: that is to say that underneath it acts exactly like a message send to the accessor for that variable. As such, all three of the following are equivalent:
self.myVariable = obj;
[self setMyVariable:obj];
objc_msgSend(self, #selector(setMyVariable:), obj);
Of course, this means that using dot-syntax actually results in a full message send, meaning calling a new function and all the overhead that is associated with it. In contrast, using simple assignment (myVariable = obj;) incurs none of this overhead, but of course it can only be used within the instance methods of the class in question.
The #synthesize directive tells the compiler to generate accessors for your member variables, according to the specifications given in the #property directive in your .h file. (I.e., if you specify retain, the setter will retain the variable, and if you specify copy, it will copy it.)
The accessors will (unless you specify otherwise) be named propertyName and setPropertyName.
Using the . notation (note, not the self syntax as stated above) is saying that you want to use the accessors (a good thing if you are setting strings, and want to ensure the retain count is correct, for example).
So, within your class implementation:
self.bill = fred will call the
accessor setBill.
bill = fred will set bill to fred
directly, without going through the
accessor.
One of the differences I found out when starting Cocoa development is if I set variable to use a #Property/#Synthesize syntax and I didn't use self.myVariable = obj or [self setMyVariable:obj] but instead myVariable = obj, the object is not retained if obj is released later. (Assuming #Property was set up to use retain.)
The reason is the retain count is not set when using myVariable = obj and when the obj is released the count is now zero. (Unless you retain it yourself) But by using the accessor it will do the retain count for you. (Again assuming you set it up to use retain when it was declared).
Shyne
If I can add one important note to this. The answer above are all awesome, so I won't add to the technical side. But just this:
If you create a synthesized property
#synthesize myProp;
Always use the self.myProp pattern to set it.
self.myProp = newVal;
This seems really obvious, but it's important. It's true that there is simply no reason to do this, but until you really understand how the synthesized setters are created you just want to assume you HAVE to use the self. pattern to set the value.
Honest: this will save you a lot of late night debug sessions. Non-retained memory access violations are simply the worst to debug.
The self syntax uses the accessor method, the other syntax does not. This might be a big difference if the accessor does something more than simply assign the new value. See the Declared Properties part of the Objective-C tutorial.
The other answers are correct, the difference is that the dot notation causes the ivar to be changed through the accessory rather than directly.
Until you know what you're doing, I recommend you use the dot notation (i.e. self.propertyName = ...). Cocoa/Obj-C does a lot with key-value coding, and while the phone SDK doesn't take full advantage of that (with things like bindings), eventually it will. Getting used to using the accessors now will save you a lot of headaches in the future.
Using the accessor methods also give you the opportunity to override them and provide more functionality should you need to. By simply changing the value of the ivar, you rob yourself of this capability.