to know the character in a object-c nsstring object - objective-c

I have an NSString *str and I want to know if the 2nd character is equal to a. How can I do this? I'm new to objective c.

Use this:
[str characterAtIndex:1]
But I always encourage you to check documentation first!

You could also use:
[[str substringWithRange:NSMakeRange(1,1)] isEqualToString:#"a"];
Admittedly, this only becomes handy when you have longer strings for which you're searching.

Related

Unique Instances of NSString for empty or 1-char strings

I would like to understand more about the way XCode/Objective-C handle constant strings. I found a related question, but I would like more information. Consider the following code:
NSString *a = [[NSString alloc] initWithUTF8String:[[_textFieldA stringValue] UTF8String]];
NSString *b = [[NSString alloc] initWithUTF8String:[[_textFieldB stringValue] UTF8String]];
NSString *c = [a copy];
NSString *d = [a mutableCopy];
Note that the textFields are just a way to set the strings at runtime ensuring that the compiler doesn't get too smart on me and build in a single instance.
If my text fields are empty, or contain a single character such as "x" or "$", then a == b == c == the same constant NSString instance. If I instead provide "xy", then a == c != b. d is always unique, as one might expect since it is mutable.
Now normally this wouldn't be an issue, I'm not trying to modify the contents of these strings, however, I am working on a system where I frequently use objc_setAssociatedObject. So here now I might come accross an empty string, and then set associated object data on it, and then have another empty string and collide with the first.
I have, for the moment, solved my issue by creating mutable strings instead.
So my questions:
Is this an Objective-C specification, or an XCode excentricity?
Does anyone know how the instance is determined? Why "x" get's one instance, but not "xy"? I would think some internal dictionary is involved and there's no good reason to stop at 1 character.
Is there a way to turn this off, so all empty strings are unique instances, or other suggestions?
I am using XCode 5.1.1, OSX 10.9.4, SDK 10.9.
Thank you!
Is this an Objective-C specification, or an XCode excentricity?
It is just implementation detail. Not documented any where. These kind of behaviour may changed in future without notice.
Does anyone know how the instance is determined? Why "x" get's one instance, but not "xy"? I would think some internal dictionary is involved and there's no good reason to stop at 1 character.
No until someone able to access source code want to share the details with us.
Is there a way to turn this off, so all empty strings are unique instances, or other suggestions?
No way to turn it off. Don't use objc_setAssociatedObject with NSString
As #Ken Thomases said in comment
In general, it probably doesn't make sense to use objc_setAssociatedObject() with any value class.
Some other examples are NSNumber, NSData and NSValue. They are often cached and reused.

How to split strings into substrings in iOS

I have a string like this.
NSString *str=#"-85.33,45.78,0.0000 -85.78,46.98,0.000 -85.98,47.678,0.0000";
I have to extract individual strings from the above into an array.
The above string is 3 sets of longitude,latitude,altitude values. these are separated by "," and spaces. I have to extract longitude values into an array and latitude to another array.
Can anyone please suggest a solution.
You could use the componentsSeparatedByString: method of NSString, or you could use the NSScanner class. You could even use componentsSeparatedByString: to split on spaces, and then use NSScanner to parse the numbers out of each substring.
Let me give you a hint. If you have a say a NSString, you can see what methods (with descriptions) are available by command-clicking on NSString in XCode. Then you would have seen componentsSeparatedByString:
The beautiful thing is this works for all objects. At least take a look before asking.

Bug with NSString componentsSeparatedByString?

I've been trying to read sections of a string into an array and encountered some problems. Though my task is more complicated, even a simple example case like the one below gives the same problem: the code compiles and runs but the the size of the strings array is always one and the only thing that's contained in strings[0] is "__NSArrayM".
NSString *string = #"John, Bob, Jane";
NSArray *strings = [string componentsSeparatedByString: #", "];
Thanks in advance for any ideas!
When you say "the size of the strings array", do you mean what you get from [strings count] or something else? Also, Objective-C doesn't let you access NSArray elements with the square bracket notation, so if you're literally calling strings[0] you're doing some pointer math on the Array object that you don't intend to be doing.

NSString format question

Here are two ways to make a NSString.
NSString *sBody = [NSString stringWithString:#"Hello"]
versus
NSString *sBody = #"Hello"
Most of the time, I see it the first way. But is it also "clean" to use the second, or is it better to not use it?
Thanks and have a nice day!
They are equivalent. It's less code to use the literal (the second example), so I would just use that.
It's the same, the first way you're helping the compiler but it already does a great job optimizing string vars.

Objective-C String-Replace

I want to replace multiple elements in my string in Objective-C.
In PHP you can do this:
str_replace(array("itemtoreplace", "anotheritemtoreplace", "yetanotheritemtoreplace"), "replacedValue", $string);
However in objective-c the only method I know is NSString replaceOccurancesOfString. Is there any efficient way to replace multiple strings?
This is my current solution (very inefficient and.. well... long)
NSString *newTitle = [[[itemTitleField.text stringByReplacingOccurrencesOfString:#"'" withString:#""] stringByReplacingOccurrencesOfString:#" " withString:#"'"] stringByReplacingOccurrencesOfString:#"^" withString:#""];
See what I mean?
Thanks,
Christian Stewart
If this is something you're regularly going to do in this program or another program, maybe make a method or conditional loop to pass the original string, and multi-dimensional array to hold the strings to find / replace. Probably not the most efficient, but something like this:
// Original String
NSString *originalString = #"My^ mother^ told me not to go' outside' to' play today. Why did I not listen to her?";
// Method Start
// MutableArray of String-pairs Arrays
NSMutableArray *arrayOfStringsToReplace = [NSMutableArray arrayWithObjects:
[NSArray arrayWithObjects:#"'",#"",nil],
[NSArray arrayWithObjects:#" ",#"'",nil],
[NSArray arrayWithObjects:#"^",#"",nil],
nil];
// For or while loop to Find and Replace strings
while ([arrayOfStringsToReplace count] >= 1) {
originalString = [originalString stringByReplacingOccurrencesOfString:[[arrayOfStringsToReplace objectAtIndex:0] objectAtIndex:0]
withString:[[arrayOfStringsToReplace objectAtIndex:0] objectAtIndex:1]];
[arrayOfStringsToReplace removeObjectAtIndex:0];
}
// Method End
Output:
2010-08-29 19:03:15.127 StackOverflow[1214:a0f] My'mother'told'me'not'to'go'outside'to'play'today.'Why'did'I'not'listen'to'her?
There is no more compact way to write this with the Cocoa frameworks. It may appear inefficient from a code standpoint, but in practice this sort of thing is probably not going to come up that often, and unless your input is extremely large and you're doing this incredibly frequently, you will not suffer for it. Consider writing these on three separate lines for readability versus chaining them like that.
You can always write your own function if you're doing something performance-critical that requires batch replace like this. It would even be a fun interview question. :)
Considered writing your own method? Tokenize the string and iterate through all of them replacing one by one, there really is no faster way than O(n) to replace words in a string.
Would be a single for loop at most.
Add the # to the start of the all the strings, as in
withString:#""
It's missing for a few.