Assign to NSString after alloc/init - objective-c

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]

Related

Understanding Instantiation in Objective-C

I’m currently trying to learn Objective-C by reading books and online tutorials, also referring to the Apple documentation but some things just don’t click. I have a question about classes, I have been using the NSString for a while now without putting too much attention on how it is used.
I was under the impression that in order for someone to be able to use a method from a certain class in Objective-C you first needed to instantiate it, something like…
ClasssName *varName = [[ClassName alloc]init];
Then you would call methods like...
[varName someMethod];
But looking at how the NSString is used I’m now I little confused, for instance here is how we would normally use it...
NSString *someString = #"some text here";
[someString stringByAppendingFormat: #"some text = %d", 3];
Following what I have read about classes we would need to do something like the following instead.
NSString *someString = [[NSString alloc]initWithString: #"some text here"];
[someString stringByAppendingFormat: #"some text = %d", 3];
Can someone explain why some classes do not require instantiation before using its methods?
Objective-C knows some abbreviations that are called literals. The compiler is aware of the special notation. A string literal is compiled into the binary and exits throughout the lifetime of an app.
For most cases it will behave like an object created on runtime.
if two literals are identical, only one object will be created and live forever
if you create NSString *string = [[NSString alloc] initWithString:#"My String"]; with #"My String" being used as a literal before, also string can point to it.
Since Apple LLVM Compiler 4.0 Objective-C knows some more literals. But in contrast to string literals these literals are created during runtime through convenient initializers.
Note that
[someString stringByAppendingFormat: #"some text = %d", 3];
does not change someString. It returns a new string object.
NSString *newString = [someString stringByAppendingFormat: #"some text = %d", 3];
The #"Text" syntax gives you an autoreleased string back, it can be thought of as a shorthand.
when you write
[[NSString alloc]initWithString: #”some text here”];
you conceptually create an autoreleased string with #”some text here” and then you create a retained new string with initWithString.

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.

Basic difference between following NSString assignment calls

// 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.

When not to alloc and init an NSString

Whenever I need to create a new NSString variable I always alloc and init it. It seems that there are times when you don't want to do this. How do you know when to alloc and init an NSString and when not to?
Whenever I need to create a new NSString variable I always alloc and init it.
No, that doesn't make sense.
The variable exists from the moment the program encounters the point where you declare it:
NSString *myString;
This variable is not an NSString. It is storage for a pointer to an NSString. That's what the * indicates: That this variable holds a pointer.
The NSString object exists only from the moment you create one:
[[NSString alloc] init];
and the pointer to that object is only in the variable from the moment you assign it there:
myString = [[NSString alloc] init];
//Or, initializing the variable in its declaration:
NSString *myString = [[NSString alloc] init];
Thus, if you're going to get a string object from somewhere else (e.g., substringWithRange:), you can skip creating a new, empty one, because you're just going to replace the pointer to the empty string with the pointer to the other one.
Sometimes you do want to create an empty string; for example, if you're going to obtain a bunch of strings one at a time (e.g., from an NSScanner) and want to concatenate some or all of them into one big string, you can create an empty mutable string (using alloc and init) and send it appendString: messages to do the concatenations.
You also need to release any object you create by alloc. This is one of the rules in the Memory Management Programming Guide.
If you want to initialise it to a known value, there is little point in using alloc, you can just use a string literal:
NSString* myStr = #"Some value";
If you want to initialise it with a format or whatever, but don't need it to stick around beyond the current autorelease pool lifetime, it's a bit neater to use the class convenience methods:
NSString* myTempStr = [NSString stringWithFormat:#"%d", myIntVar];
If you need its lifetime to go beyond that, either alloc/init or else add a retain to the previous call. I tend to slightly prefer the latter, but the two are pretty much equivalent. Either way you will need a balancing release later.
Note that, since NSString is not mutable, this sort of thing is not only unnecessary but actively wrong:
// don't do this!
NSString* myStr = [[NSString alloc] initWithString:#""];
myStr = someOtherStr;
since it leaks the initial placeholder value.
It seems that there are times when you don't want to do this.
I can't think of any time when I would want to alloc/init a NSString. Since NSStringgs are immutable, you pretty much always create new strings by one of:
convenience class method e.g.
NSString* foo = [NSString stringWithFormat:...];
literal
NSString* foo = #"literal";
NSString instance method
NSString* foo = [bar uppercaseString];
copy from mutable string
NSString* foo = [mutableBar copy]; // foo needs to be released or autoreleased in this case
I'm guessing that you are referring to using StringWithString or similar instead of initWithString? StringWithString alloc and inits for you under the hood and then returns an autoreleased string.
If you don't need to do any string manipulation other than to have the string, you can use NSString *str = #"string";
In general with iOS, the tighter you manage your memory the better. This means that if you don't need to return a string from a method, you should alloc init and then release it.
If you need to return a string, of course you'll need to return an autoreleased string. I don't think its any more complicated than that.

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.