Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.67 MB, 89 trang )
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 face enter her name */
}
Another thing that you might want to know about strings is how you to 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);
You can use the %s format specifier to print a C String out to the console,.
In comparison, 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:
76 | Chapter 1: The Basics
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 loca
tion 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);
}
The search done by the rangeOfString: method of NSString class is casesensitive.
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 optionsparameter is of type NSString
CompareOptions.
enum {
NSCaseInsensitiveSearch = 1,
NSLiteralSearch = 2,
NSBackwardsSearch = 4,
NSAnchoredSearch = 8,
NSNumericSearch = 64,
NSDiacriticInsensitiveSearch = 128,
NSWidthInsensitiveSearch = 256,
NSForcedOrderingSearch = 512,
NSRegularExpressionSearch = 1024
};
typedef NSUInteger NSStringCompareOptions;
1.21 Allocating and Making Use of Strings | 77
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 casesensitivity 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".
See Also
XXX
78 | Chapter 1: The Basics
1.22 Allocating and Making Use of Numbers
Problem
You need to use integral values or encapsulate numbers in objects.
Solution
Use NSNumber for an object-oriented approach to handling numbers. If you require simple numbers (non-objects), use NSInteger to hold signed (positive and negative) values,
NSUInteger to hold unsigned (only positive or zero) values, and CGFloat and double to
hold floating point values.
Discussion
Just as we place strings inside instances of NSString, we can place numbers inside instances of NSNumber. Why, you might ask? The answer is simple: to have allow an object
to carry the value of our numbers so that we can save this value to disk easily, load it
from disk, and simply allow a single object to carry signed and unsigned integral and
floating point values, without the need for typecasting or defining multiple variables.
The possibilities are virtually endless.
Let's have a look at constructing instances of NSNumber:
NSNumber
NSNumber
NSNumber
NSNumber
*signedNumber = [NSNumber numberWithInteger:-123456];
*unsignedNumber = [NSNumber numberWithUnsignedInteger:123456];
*floatNumber = [NSNumber numberWithFloat:123456.123456f];
*doubleNumber = [NSNumber numberWithDouble:123456.1234567890];
Just as we placed signed and unsigned integers and floating point values into an instance
of NSNumber class, we can retrieve those values back using some really handy instance
methods of NSNumber class, as shown here:
NSNumber
NSNumber
NSNumber
NSNumber
*signedNumber = [NSNumber numberWithInteger:-123456];
*unsignedNumber = [NSNumber numberWithUnsignedInteger:123456];
*floatNumber = [NSNumber numberWithFloat:123.123456f];
*doubleNumber = [NSNumber numberWithDouble:123.1234567890];
NSInteger signedValue = [signedNumber integerValue];
NSUInteger unsignedValue = [unsignedNumber unsignedIntegerValue];
CGFloat floatValue = [floatNumber floatValue];
double doubleValue = [doubleNumber doubleValue];
NSLog(@"signedValue = %ld, \n"\
"unsignedValue = %lu \n"\
"floatValue
= %f
\n"\
"doubleValue
= %f",
(long)signedValue,
(unsigned long)unsignedValue,
floatValue,
doubleValue);
1.22 Allocating and Making Use of Numbers | 79
Here are the methods of NSNumber that we used in this code to actually generate instances
of NSNumber class:
numberWithInteger:
Encapsulates an integer into an instance of NSNumber.
numberWithUnsignedInteger:
Encapsulates an unsigned integer (only positive or zero numbers) into an instance
of NSNumber.
numberWithFloat:
Encapsulates a floating point value into an instance of NSNumber.
numberWithDouble:
Encapsulates a double value into an instance of NSNumber.
And here are the methods which we used to extract pure numbers from instances of
NSNumber:
integerValue
Returns an integer of type NSInteger from the NSNumber on which this method is
called.
unsignedIntegerValue
Returns an unsigned integer of type NSUInteger from the NSNumber on which this
method is called.
floatValue
Returns a floating point value of type CGFloat from the NSNumber on which this
method is called.
doubleValue
Returns a double value of type double from the NSNumber on which this method is
called.
If you want to compare a number to a string, simply convert it to any of the raw integral/
float values that you think can contain the whole of that number, and then format your
string using a format identifier that suits your data. For instance, to turn an unsigned
integer into an instance of NSString, you can use the %lu format specifier, like so:
NSNumber *unsignedNumber = [NSNumber numberWithUnsignedInteger:123456];
/* Convert an unsigned integer inside an NSNumber to NSString */
NSString *numberInString =
[NSString stringWithFormat:@"%lu",
(unsigned long)[unsignedNumber unsignedIntegerValue]];
NSLog(@"numberInString = %@", numberInString);
Keep in mind that any class method of NSNumber class that starts with numberWith
returns an autorelease instance of that NSNumber. To remove the burden on your autorelease pools, you can use the initWith... methods of the NSNumber class after allocating
your number, like so:
80 | Chapter 1: The Basics