i've noticed that all #"" objects create one reference for all times it is executed.
NSString *s1=#"";
NSString *s2=#"";
In this sample s1 equals s2.
#"" will create one pointer in all cases, every time i use it?
Can i rely on this feature in comparing strings in objective-c?
Or simply, can i use this statement, if i want to assure that my string is empty:
if(s == #""){
//do something
}
Yes Objective C has an optimization in the compiler that simply points all equivalent string literals to the same string in memory to avoid allocating unnecessary resources. This feature is reliable but there is a chance that this will not always happen as documented in the Objective C language specs.
you should use
if([s isEqualToString:#""])
Related
for example:
NSString *myString = [[NSString alloc] init];
if (nil == myString) {
return;
}
Need I do this??Thank you!
No, you don't need to do that, and I can't say I've ever seen code that made pervasive use of that pattern.
Also, the if statement can be shortened to:
if (! myString) {
return;
}
...which is equivalent though no less superfluous. Checking for nil can be useful, but is typically not done immediately after object instantiation. Instead the typical case is to do it to ensure that an object is not over-released, for instance using a pattern like:
if (myObj) {
[myObj release];
myObj = nil;
}
Note that calling any method on nil is allowed in Objective-C, so less harm is caused by an unexpected nil value floating around than in languages like Java where attempting to do anything with a null reference throws an exception.
Objective-C allows to call on nil pointers, that differs the language from many others and allows to skip some checks. Of course, it's still wise to check for == nil in some particular cases, however, you don't have to check every step in the code. Take a look at Apple's documentation and samples and try to follow their style.
Frankly, most iPhone app code produced these days assumes that an out-of-heap condition (the only logical reason for such a simple instantiation operation to fail) never occurs in normal operation. Only when creating large (eg, image) objects might one check for allocation failure.
Of course, init routines can fail for a host of reasons, so checking for nil following a complex instantiation operation may be warranted (depending on the object type). (And remember that many other methods of some objects can return nil under some circumstances as well, so you need to read the specs and code accordingly.)
For non-retained string declarations, are these three lines the same?
NSString *list2 = self.map;
NSString *list2 = [NSString stringWithFormat:#"%#", self.map];
NSString *list2 = [NSString stringWithString:self.map];
They all create an autoreleased string object, right? Is there a preferred method among these, or are there any differences in the memory usage or behavior of "list2" depending on these methods?
For some reason, I find the manipulation of strings in objective-C the most confusing transition from other languages.
The simple fact, You don't own the object in the above three cases,
So you could use either,
This is more related to choice of developer then performance.
Go through the Memory Management Programming Guide
They all create an autoreleased string object, right?
No, the first one merely assigns the pointer returned by string.map to list2. The second and third ones theoretically create new NSStrings that you don't own and assign them to list2. However, if string.map returns an immutable string, the third one will probably give you the same pointer (possibly retained and autoreleased).
In all cases you do not own the (new) string. That's actually all you need to know. They may be autoreleased, but it is not relevant to you using them.
Does anyone know if the following code could be problematic:
NSString *addchar = nil;
if (case1)
addChar = [[firstname substringToIndex:1] capitalizedString];
else
addChar = [[fullname substringToIndex:1] capitalizedString];
Assume that firstname and fullname aren't null or empty. Does initializing the NSString object and setting it to 'nil' cause some possible problem? It seems to cause my app to freeze, but only for a very few users, and only those users, but it doesn't have anything to do with different input strings or empty strings. So I'm trying to isolate the problem, but I don't know the difference between
NSString *addChar;
and
NSString *addChar = nil;
Thanks.
Either form is perfectly acceptable. The problem you're having is elsewhere. I recommend doing some code profiling with Instruments to figure out where this issue is occurring.
Without the nil initializer, in some cases your variable may be initialized with garbage (whatever was in the memory space previously). There are specific rules regarding which types of variables (scope-based, static storage, etc.) are nil-initialized automatically for you, but I've always found that it's easier to explicitly initialize all variables instead of memorizing those rules.
That said, because both branches of your if statement clobber any previous value of addChar, there should not be any case in which you can see an invalid value. But it's certainly not hurting anything to explicitly initialize to nil, and if a future maintainer comes along and changes the code paths you might find that the initializer saves you!
You should always initialize to nil if variable is not initialized otherwise.
You can send messages to nil they will be ignored.
NSString * str = nil;
NSLog(#"%#", [str description]);
Outputs:
2009-12-15 08:59:03.352 x[11775] (nil)
Of course I don't need to call description explicitly, I'm just demonstrating call to nil.
There is no difference here since you don't read addChar in your code. Moreover, the compiler may sometimes initialize addChar to nil for you if you don't do it explicitly (depending on the scope of addChar's declaration).
See related question at this place.
From now on, when you use ARC, the strong, weak, and autoreleasing stack variables are initialized to nil:
https://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW5
Additionally, since dawn of times, in ObjC the instance variables are initialized to zero:
Are instance variables set to nil by default in Objective-C?
I want to compare if an variable A represents the same object as variable B does.
Could I do that with the == operator?
Or what else is this exactly looking at? I think I need to check for the memory adress of the object where the variable is pointing to, right?
The == operator tests whether the two expressions are the same pointer to the same object. Cocoa calls this relation “identical” (see, for example, NSArray's indexOfObjectIdenticalTo:).
To test whether two objects are equal, you would send one of them an isEqual: message (or a more specific message, such as isEqualToString:, if it responds to one), passing the other object. This would return YES if you really only have one object (equal to itself, obviously) or if you have two objects that are equal. In the latter case, == will evaluate to NO.
The == tells you if two pointers are pointing to the same object. isEqual tells you if the contents of two objects are the same (but not necessarily the actual same object). A little confusing.
Try this code to understand it better:
NSString *aString = [NSString stringWithFormat:#"Hello"];
NSString *bString = aString;
NSString *cString = [NSString stringWithFormat:#"Hello"];
if (aString == bString)
NSLog(#"CHECK 1");
if (bString == cString)
NSLog(#"CHECK 2");
if ([aString isEqual:bString])
NSLog(#"CHECK 3");
if ([bString isEqual:cString])
NSLog(#"CHECK 4");
// Look at the pointers:
NSLog(#"%p", aString);
NSLog(#"%p", bString);
NSLog(#"%p", cString);
[objectA isEqual:objectB] is usually a good choice. Note that some classes may have more specialized equality functions. (isEqualToString: et.al.) These generally test not if they are the same object, but if the objects are equal, which is a distinct concept. (Two string objects can be equal, even if they don't have the same memory address.)
The two other answers correctly answer the question in your title. The correct answer to the completely different question in your body text, however, is: yes, the == operator is correct for testing whether two variables refer to the same object.
I'm just starting out with iphone development and ran across some example code that used #"somestring"
someLabel.txt = #"string of text";
Why does the string need the '#'? I'm guessing it's some kind of shortcut for creating an object?
It creates an NSString object with that string as opposed to the standard c char* that would be created without the '#'
In Objective-C, the syntax #"foo" is an immutable, literal instance of NSString.
Just an interesting side note... NSString literals created by using the #"..." notation are not autoreleased. They essentially just hang around until your program terminates.
Just a caution that if you want to maintain control over whether or not this object gets released (freed) down the road you may want to consider using something like:
[NSString stringWithString:#"..."];
...instead. This would create an autoreleased version of the same string that will be freed from memory next time the "autorelease pool is drained".
Just food for thought.
Cheers-