The NSString
and NSMutableString
classes allow you to store a string of characters in memory. The
NSString
class is immutable, meaning
that once it is created, its contents cannot be modified. Mutable
strings represented with the NSMutableString
can be modified once they are
created. We will see an example of both of these classes very
soon.
Objective-C strings should be placed inside double quotes. The starting double-quote
should be prefixed with an at sign (@). For instance, the sentence
Hello, World
, represented as a string
in Objective-C, is written like so:
@"Hello, World"
There are various ways of placing a string inside an instance of
NSString
or NSMutableString
classes. Here is how:
NSString
*
simpleString
=
@"This is a simple string"
;
NSString
*
anotherString
=
[
NSString
stringWithString:
@"This is another simple string"
];
NSString
*
oneMorestring
=
[[
NSString
alloc
]
initWithString:
@"One more!"
];
NSMutableString
*
mutableOne
=
[
NSMutableString
stringWithString:
@"Mutable String"
];
NSMutableString
*
anotherMutableOne
=
[[
NSMutableString
alloc
]
initWithString:
@"A retained one"
];
NSMutableString
*
thirdMutableOne
=
[
NSMutableString
stringWithString:
simpleString
];
If you are working with strings, you are probably going to need
the length of your string objects from time to time to make specific
decisions at runtime. Imagine this scenario: you have asked your user to
enter her name in a text field. When she presses the button to confirm
her name, you would need to check whether she has in fact entered her
name. You can do this by calling the length
method on an instance of NSString
or any of its subclasses, including
NSMutableString
, as shown
here:
NSString
*
userName
=
...;
if
([
userName
length
]
==
0
){
/* The user didn't enter her name */
}
else
{
/* The user did in fact enter her name */
}
Another thing that you might want to know about strings is how you can convert a
string to its equivalent integral value, i.e., converting a string to an
integer, float, or double. You can use the integerValue
, floatValue
, and doubleValue
methods of NSString
(or any of its subclasses) to
retrieve the integer, float and double values of a string, like
so:
NSString
*
simpleString
=
@"123.456"
;
NSInteger
integerOfString
=
[
simpleString
integerValue
];
NSLog
(
@"integerOfString = %ld"
,
(
long
)
integerOfString
);
CGFloat
floatOfString
=
[
simpleString
floatValue
];
NSLog
(
@"floatOfString = %f"
,
floatOfString
);
double
doubleOfString
=
[
simpleString
doubleValue
];
NSLog
(
@"doubleOfString = %f"
,
doubleOfString
);
The output of this code is:
integerOfString
=
123
floatOfString
=
123.456001
doubleOfString
=
123.456000
If you would like to work with C Strings, you can! You will use
them like NSString
without the leading at sign, like so:
char
*
cString
=
"This is a C String"
;
If you want to convert an NSString
to a C
String, you must use the UTF8String
method of NSString
, like so:
const
char
*
cString
=
[
@"Objective-C String"
UTF8String
];
NSLog
(
@"cString = %s"
,
cString
);
Note
You can use the %s
format
specifier to print a C String out to the console. In contrast,
use the %@
format specifier to
print out NSString
objects.
To convert a C String to NSString
, you must use the stringWithUTF8String:
method of the NSString
class, as demonstrated here:
NSString
*
objectString
=
[
NSString
stringWithUTF8String:
"C String"
];
NSLog
(
@"objectString = %@"
,
objectString
);
In order to find a string inside another string, you can use the
rangeOfString:
method of NSString
. The return value of this method is
of type NSRange
:
typedef
struct
_NSRange
{
NSUInteger
location
;
NSUInteger
length
;
}
NSRange
;
If the string that you are looking for (needle) is found inside the target string
(haystack), the location
member of
the NSRange
structure will be set to
the zero-based index of the first
character of needle in haystack. If needle cannot be found in
haystack, the location
member gets set to NSNotFound
. Let’s have a look at an
example:
NSString
*
haystack
=
@"My Simple String"
;
NSString
*
needle
=
@"Simple"
;
NSRange
range
=
[
haystack
rangeOfString:
needle
];
if
(
range
.
location
==
NSNotFound
){
/* Could NOT find needle in haystack */
}
else
{
/* Found the needle in the haystack */
NSLog
(
@"Found %@ in %@ at location %lu"
,
needle
,
haystack
,
(
unsigned
long
)
range
.
location
);
}
Note
The search done by the rangeOfString:
method of NSString
class is case-sensitive.
Note
In the Platform
Dependencies section of the String Programming Guide published by Apple, it’s been
explained why we need to typecast integral values with specifiers such
as unsigned long
. I highly
recommend that you visit the aforementioned guide online.
If you want to have more control over how your search is done on a string, you can
use the rangeOfString:options:
method, where the options
parameter
is of type NSStringCompareOptions
.
enum
{
NSCaseInsensitiveSearch
=
1
,
NSLiteralSearch
=
2
,
NSBackwardsSearch
=
4
,
NSAnchoredSearch
=
8
,
NSNumericSearch
=
64
,
NSDiacriticInsensitiveSearch
=
128
,
NSWidthInsensitiveSearch
=
256
,
NSForcedOrderingSearch
=
512
,
NSRegularExpressionSearch
=
1024
};
typedef
NSUInteger
NSStringCompareOptions
;
As you can see, the values in this enumeration are multiples of 2. That indicates that you can mix them with the logical OR operator (the | pipe character). Let’s say we want to search for a string inside another string but we are not concerned about the case-sensitivity of the search. All we want is to find a string inside another string, whether the case matches or not. Here is how we can do it:
NSString
*
haystack
=
@"My Simple String"
;
NSString
*
needle
=
@"simple"
;
NSRange
range
=
[
haystack
rangeOfString:
needle
options:
NSCaseInsensitiveSearch
];
if
(
range
.
location
==
NSNotFound
){
/* Could NOT find needle in haystack */
}
else
{
/* Found the needle in the haystack */
NSLog
(
@"Found %@ in %@ at location %lu"
,
needle
,
haystack
,
(
unsigned
long
)
range
.
location
);
}
You can see that we are using the rangeOfString:options:
method of NSString
with the NSCaseInsensitiveSearch
value, which tells the
runtime that we want the search to be performed without any regard to
case-sensitivity.
Mutable strings are similar to immutable strings. However, they can be modified during runtime. Let’s see an example:
NSMutableString
*
mutableString
=
[[
NSMutableString
alloc
]
initWithString:
@"My MacBook"
];
/* Add string to the end of this string */
[
mutableString
appendString:
@" Pro"
];
/* Remove the "My " string from the string */
[
mutableString
replaceOccurrencesOfString:
@"My "
withString:
[
NSString
string
]
/* Empty string */
options:
NSCaseInsensitiveSearch
/* Case-insensitive */
range:
NSMakeRange
(
0
,
[
mutableString
length
])];
/* All to the end */
NSLog
(
@"mutableString = %@"
,
mutableString
);
When the mutableString
string
gets printed to the console, you will see this:
mutableString
=
MacBook
Pro
You can see that we started with the string "My MacBook"
and then removed the "My "
string from that original string. So now
we have "MacBook"
. After this, we
appended the string " Pro"
to the end
of this string to get the final value, which is "MacBook Pro"
.
Get iOS 6 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.