Basic difference between following NSString assignment calls - objective-c

// Directly assigning the value.
NSString *str = [objDictionary objectForKey:#"attributeName"];
// Assigning with convenience method
NSString *str = [NSString stringWithFormat:#"%#", [objDictionary objectForKey:#"attributeName"]];
// Assigning after being owner to that object.
NSString *str = [[NSString alloc] initWithString:#"%#", [objDictionary objectForKey:#"attributeName"]];
In what cases, We need to identify which one needed to be used in code. ???
Any Reference links for difference between the same???
Or can someone answer the question in depth???
Thanks for the help.

NSString *str = [objDictionary objectForKey:#"attributeName"];
This is the declaration where you want to user local variable with autorelease memory assigned
i.e. you don't need to worry about memory allocation/deallocation.
NSString *str = [NSString stringWithFormat:#"%#", [objDictionary objectForKey:#"attributeName"]];
This method is useful when you need to combine different types in single string
i.e. integer/float with string
for e.g.
NSString *str = [NSString stringWithFormat:#"%# and %d", [objDictionary objectForKey:#"attributeName"], 5];
This will result in 'your value and 5'
NSString *str = [[NSString alloc] initWithString:#"%#", [objDictionary objectForKey:#"attributeName"]];
This is the assignment where you are allocating memory and you need to have that variable to use some other place so it will be there until and unless you release the memory of that variable.
Make sure when you allocate memory you release memory yourself as you are the responsible one.
For further detailed study I recommend you to visit documentation for NSString which will give you idea about available class/instance methods and how to use.

Assuming your dictionary contains a string, under ARC, these are all identical. With manual reference counting, the first two are autoreleased and the last one is retained.
For a reference guide, you can't do much better than the NSString class reference.

Related

Nature of NSString [duplicate]

This question already has answers here:
Difference between NSString literals
(5 answers)
Closed 9 years ago.
Such a basic question, but i don't know the answer.What exactly the difference between:
NSString *str = #"Hello";
and
NSString *str = [[NSString alloc] initWithString:#"Hello"];
When should i use each one?
A #"" expressions is replaced at compile time1 with an instance of NSConstantString, which is a specialized subclass of NSString with a fixed memory layout2. This also explains why NSString is the only object that can be initialized at compile time3.
A [[NSString alloc]initWithString:#""] produces a NSString instance, initializes that instance with a literal expression, and releases the instance. Therefore, the object allocation is superfluous and immediately discarded. Which is why you should always use just the literal when creating immutable strings.
1 The LLVM code that rewrites the expression is RewriteModernObjC::RewriteObjCStringLiteral in RewriteModernObjC.cpp.
2 To see the NSConstantString definition, cmd+click it in Xcode.
3 Creating compile time constants for other classes would be easy but it would require the compiler to use a specialized subclass. This would break compatibility with older Objective-C versions.
When should i use each one?
NSString *str = [[NSString alloc] initWithString:#"Hello"]; //1st one
The above is redundant, and has same meaning as
NSString *str = #"Hello"; //2nd one
So always use shorter one. i.e 2nd one in my example.
EDIT:
Also see this What's the difference between NSString *s = #"string" and NSString *s = [[NSString alloc] initWithString:#"string"]?

Objective-C: What is the difference between creating an object from alloc/init and class method calls?

For example,
NSString *string = [NSString stringWithString:#"a string"];
NSString *string = [[NSString alloc] initWithString:#"a string"];
and while we're talking about strings, is there any difference by setting up a string with:
NSString *string = #"a string";
?
As a final note, this isn't a specific question about NSString. I'm asking on a wider scope of all NSObjects.
There is no difference in ARC, but prior to it there was a difference: alloc/init returns an item with ref count of at least one that you'd need to release when you don't need it, while the class method returns an autoreleased item that you'd need to retain if you would like to keep it. The ARC compiler knows all this, and takes care of retaining/releasing for you based on your ownership specifications.

Assign to NSString after alloc/init

This doesn't seem to work:
NSString *string = [[NSString alloc] init];
string = #"%#M", anotherstring;
I expect this to make "string" equal to "5M" if "anotherstring" is "5".
Is this not the right syntax? Now, I could use initWithFormat and it would work, but how can you separate it into two different lines and also work?
There are two mistakes in your code. Firstly, NSStrings are immutable, and once you allocate and initialize them, they're set, and there's no way to change them. For that, you'd have to look into NSMutableString.
Secondly, the syntax of your code makes no sense. #"%#M", anotherString is not a valid Objective-C method call. You are indeed looking for -initWithFormat: to perform the operation you want. The code should look like this:
NSString *string = [[NSString alloc] initWithFormat:#"%#M", anotherString];
Read more about NSString and how to use it in the NSString Programming Reference document, and the String Programming Guide to get a sense of how to work with strings in Cocoa and Objective-C.
This line:
string = #"%#M", anotherstring;
is syntactically correct, but it doesn't do what you want it to do. This is how you format a string:
NSString *string = [[NSString alloc] initWithFormat:#"%#M", anotherstring];
There's no point in separating it into two lines. This:
NSString *string = [[NSString alloc] init];
string = [[NSString alloc] initWithFormat:#"%#M", anotherstring];
will create an extra NSString object, and also cause a memory leak.
How about
NSString* string;
string = [[NSString alloc] initWithFormat:#"%#M", anotherString];
Keep in mind that the = operator is assignment. Any time you use it, any value was stored in your variable is overwritten with the new one. So even if your original code was syntactically correct it still has faulty semantics that would, in this case, cause a memory leak.
just make it into a property and you dont need to worry about releasing and retaining the "string" (that is if you autocreate it by using synthesize). and dont forget to autorelease the object ur assigning to the property:
self.string = [[[NSString alloc] init] autorelease]

String splitting problem

I am work on a simple program in which I split a string and a user global, I use the following code for splitting the string.
NSString *GlobleStr;//globale variable
//===============
NSString *xmlParsingResult=#"Apple,iphone";
NSArray *array = [xmlParsingResult componentsSeparatedByString:#","];
NSString *StrResult = [NSString stringWithFormat:#"%#", [array objectAtIndex:0]];
GlobleStr =[NSString stringWithFormat:#"%#",[array objectAtIndex:1]];
NSLog(#"cmd %#",StrResult);
NSLog(#"value%#",GlobleStr);
my code can split the string and o/p is cmd:Apple value:iphone
but my problem is that as soon as I call another xib then my global variable will be empty or nil and the application will crash ( it throws error like Variable is not cfstring).
Any suggestions?
It's because NSString's +stringwithFormat: method returns an autoreleased string. In a local variable this is often what you want to prevent memory leaks (otherwise you have to manually release the string when you're done with it). The problem here is that the string in GlobleStr is getting released by the autorelease pool sometime after you assign it, then when you try to access it in another place you get a crash.
The fix is this: GlobleStr = [[NSString stringWithFormat:#"%#",[array objectAtIndex:1]] retain];
As an aside, you can just do this instead:
GlobleStr = [[array objectAtIndex:1] retain];
I strongly recommend reading Apple's documentation regarding memory management in Cocoa: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html .
Finally, without seeing your code I can't say for sure, but I'd be curious to know why you're using a global variable for GlobleStr. It's a blanket statement, and there are certainly exceptions, but when programming in Cocoa there's probably a better way to structure your code.
You need to retain your global, otherwise it will be deallocated when the autorelease pool drains:
GlobleStr = [[NSString stringWithFormat:#"%#", [array objectAtIndex:0]] retain];
Remember to release it later on when you're done -- in particular, before assigning any other value to it.

NSString retain Count

Just couple of days i was working on a project and i have to see what is retain count of a string.
But it always return me "2147483647", Why it is so?
Check out this code to check it yourself.
NSString *str = [[NSString alloc] initWithString:#"Hello World"];
NSLog(#"String Retain Count: %i", [str retainCount]);
So my question is why it is not returning 1 like other objects return, why i am getting "2147483647"
Thanks in advance.
The compiler is smarter than you.
It sees #"Hello world" and thinks "Aha! A constant string!"
It then sees [[NSString alloc] initWithString:#"Hello world!"] and thinks "Aha! An immutable object created with a constant string!"
It then collapses both of them down into a single NSConstantString, which has a retainCount of UINT_MAX, so that it can never be released.
NSString *str = [[NSString alloc] initXXX
usually would allocate some RAM and return you a pointer. This RAM would then be subject to releases and reatins. However, when you do:
NSString *str = [[NSString alloc] initWithString:#"Hello World"];
the string returned is #"Hello World", which is already allocated because it was a string literal. Since it is a string literal, there is no way to release it, and thus the system has to mark it as unreleasable. The way it does that is to set its retain count to the max integer value.
NString *str = [[NSString alloc] initWithFormat:#"Hello World. Today is #%", todayDate];
This string will have a retainCount of 1. Although there is a string constant in there, it is appended to by another string. Since you can't modify that constant string, a copy of the "Hello World. " string is made, and the content of the todayDate string is added to that. That memory now is given ownership to the caller, with a retainCount of 1.
The string is being optimized at compile-time to a statically allocated instance of NSString in order to save on some variable overhead and the like. You're seeing such a high retain count because static strings have a retain count of the maximum integer on whatever platform you're developing on.