views:

94

answers:

3

I am kind of confused by the behavior of NSString *str..

I assigned it in several ways, sometimes it works, and sometimes it becomes null.

NSString *str = @"/hi/hello"; // this one always works
// this sometimes becomes null after the function ends
NSString *str2 = [str lastPathComponent]; 
// as above
NSString *str3 = [NSString stringWithString:str2];
NSString *str4 = [NSString initWithString:str3];

I am not quite familiar with the object behavior of Obj-C, is it just like C++?

If so, how can I do assignment safely like

string str = "hi";
string str2 = str;

behaves in C++?

ex: I declare a string in my .h file,

how to assign it safely that it wouldn't become NULL after a function ends?

I know it's a very basic question, but I can't find the answer in NSString reference page.

Really thanks for any help!

+2  A: 

I assume you're not using garbage collection? If this is the case then you need to retain the string.

NSString* str2 = [[str lastPathComponent] retain];

I suggest you do some reading on objective-c memory management.

Gary
Thank you, I'll read it.. > <
Frost
Only true if `str2` (et al) are instance variables or global variables. You don't need to retain everything you assign to local variables.
Peter Hosey
Agreed but he did state that the variable was becoming nil once the function ended which implies that is not a local.
Gary
An instance variable or global variable won't become `nil` after the method ends, either. They would be quite useless if they did.
Peter Hosey
Not as a direct result of leaving the method but if you are not using GC and such variables have been added to an autorelease pool then it is highly likely that they will be released very soon after.
Gary
Released, yes. The objects will die. The variable, however, will not somehow be reset to contain `nil`; it will still contain the pointer to the (now dead) object.
Peter Hosey
+6  A: 

The behaviour is not just like C++. Objects are reference-counted. If you want to keep one around, you must place a claim on it.

If you create the object yourself with a method whose name includes the word alloc, new or copy then you have ownership already. This is like a C++ new. (When you have created an object with alloc, you need also to initialise it with some method whose name begins init. But you have to create it first. In C++ both things would be considered parts of the single act of construction.)

Objects you receive from other methods (such as two of the three NSString methods you mention) are only transiently available unless you explicitly claim ownership by calling [object retain]. You only need to do this if you want to keep them around beyond the immediate context. (There isn't really an equivalent to this in C++.)

However you gain ownership, you must relinquish it when you are finished by calling [object release]. This sort of like a C++ delete, except that the object isn't actually destroyed until all ownership claims are released.

Getting to grips with this is really really really important, perhaps the only important thing you need to know to use Objective-C. Read the object ownership documentation carefully and you'll be sorted.

walkytalky
Thank you so much!
Frost
It's also worth noting that objects do not magically become nil, even when they're dealloced. Accessing a dealloced object is just invalid — it might crash your program or it might do something much weirder.
Chuck
+2  A: 
NSString *str = @"/hi/hello"; 

This works because it creates a string literal. Answers to this question are worth a read to understand these in Objective-C

http://stackoverflow.com/questions/25746/whats-the-difference-between-a-string-constant-and-a-string-literal

In all these cases you are creating autoreleased strings. These will be deallocated when you return to the application's runloop.

NSString *str2 = [str lastPathComponent]; 
NSString *str3 = [NSString stringWithString:str2];

In this last one I assume you meant [[NSString alloc] initWithString:str3]

This creates a string that is retained. But this isn't a good way to create static strings. You should create static strings in your implementation file like this

static NSString *myConstant = @"constantString"
Ira Cooke
Thanks, it's clear!
Frost