一. 数字对象
1. 在C语言中我们讨论的所有数字数据类型,int型、float型和long型都是OC语言中的基本数据类型,但他们都不是对象。如果需要存储基本数据类型(包括char型),可以使用NSNumber类,它会根据这些数据的类型创建对象。以下是数字对象相见的操作方法。
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSNumber *myNumber, *floatNumber, *intNumber; NSInteger myInt; //integer整型 intNumber = [NSNumber numberWithInteger: 100]; myInt = [intNumber integerValue]; NSLog(@"%li", (long) myInt); //long型值 myNumber = [NSNumber numberWithLong: 0xabcdef]; NSLog(@"%lx", [myNumber longValue]); //char型值 myNumber = [NSNumber numberWithChar: 'X']; NSLog(@"%c", [myNumber charValue]); //float型值 floatNumber = [NSNumber numberWithFloat: 100.00]; NSLog(@"%g", [floatNumber floatValue]); //double myNumber = [NSNumber numberWithDouble: 12345e+15]; NSLog(@"%lg", [myNumber doubleValue]); // 发生错误 NSLog(@"%li", (long) [myNumber integerValue]); //验证两个Number是够相等 if( [intNumber isEqualToNumber: floatNumber] == YES ) NSLog(@"Numbers are equal"); else NSLog(@"Numbers are not equal"); //验证一个Number是否小于,等于或大于另一个Number if( [intNumber compare: myNumber] == NSOrderedAscending) NSLog(@"First number is less than second"); } return 0; }
2. 在if语句中,消息表达式 [intNumber isEqualToNumber: myNumber] 中使用了 isEqualToNumber:方法比较两个NSNumber对象的数值。程序会返回一个BOOL值,查看这两个值是否相等。
可以使用compare方法测试一个值是否在数值上小于、等于或大于另一个值。当消息表达式 [intNumber compare: myNumber]
中intNumber的值小于myNumber的值时,返回NSOrderedAscending;如果相等,则返回NSOrderedSame;如果第一个值大于第二个值,则返回NSOrderedDescending。
注意:不能修改前面创建的NSNumber对象的值。例如,
NSNumber *myNumber = [[NSNumber alloc] initWithInt: 50]; ... [myNumber initWithInt: 1000];
并不能正常运行。
3. 所有的数字对象必须都是新创建的,这意味着必须对NSNumber类调用numberWith···方法,或者对alloc方法的结果调用initWith···方法。
方法numberWithInt:和numberWithInteger:使用有一些差别,遵循以下一些规则:
1> 如果使用numberWithInt:方法创建一个整型数,需要使用intValue获取它的值,使用%i作为格式化字符串显示它的值。2> 如果使用numberWithInteger:方法创建一个整型数,需要使用integerValue,也可以转换为long显示或者使用stringWithFormat:将它格式化成字符串。使用%li作为格式化字符串。
方法numberWithUnsignedInt:和numberWithUnsignedInteger:的使用类似。
最近对OC语言的扩展是允许通过@表达式创建数字对象的。
intNumber = @100;
二. 字符串对象
1. NSLog函数:
NSNumber *intNumber = @100; NSLog(@"%@", intNumber);
2. description方法
OC中可以使用格式化字符%@显示数组、字典和集合的全部内容。事实上,通过覆盖继承的description方法,还可以通过格式字符显示你自己的类对象。如果不覆盖方法,NSLog仅仅显示类名和该对象在内存中的地址,这是从NSObject类继承的description方法默认的实现。
description方法的默认实现是返回类名和对象的内存地址,这样的话,使用NSLog输出
OC对象,意义就不是很大,因为我们并不关心对象的内存地址,比较关心的是对象内
部的一些成变量的值。因此,会经常重写description方法,覆盖description方法的默认
实现
比如,重写Fraction的description方法,返回成员变量numberator,denominator的值
- (NSString *)description { return [NSString stringWithFormat:@"%i/%i", numberator, denominator]; }
4. 可变对象与不可变对象
NSString类处理不可变字符,而可变字符则是用NSMutableString类处理的。基本的字符串操作如下:
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str1 = @"This is string A"; NSString *str2 = @"This is string B"; NSString *res; NSComparisonResult compareResult; //计算字符串中的字符 NSLog(@"Length of str1: %lu", [str1 length]); //将一个字符串复制到另一个字符串 res = [NSString stringWithString: str1]; NSLog(@"copy: %@",str2); //将一个字符串复制到另一个字符串的末尾 str2 = [str1 stringByAppendingString: str2]; NSLog(@"Concatentaton: %@", str2); //验证两个字符串是否相等 if([str1 isEqualToString: res] == YES) NSLog(@"str == res"); else NSLog(@"str1 !=res"); //验证一个字符串是否小于,等于或大于另一个字符串 compareResult = [str1 compare: str2]; if(compareResult == NSOrderedAscending) NSLog(@"str1 < str2"); else if (compareResult == NSOrderedSame) NSLog(@"str1 == str2"); else NSLog(@"str1 > str2"); //将字符串转换为小写 res = [str1 lowercaseString]; NSLog(@"Lowercase conversion: %@", res); NSLog(@"Oringinal string: %@", str1); //将字符串转换为大写 res = [str1 uppercaseString]; NSLog(@"Uppercase conversion: %s", [res UTF8String]); } return 0; }
声明:NSComparisonResult compareResult;用于保存后面执行的字符串比较结果。
在使用compare:方法时注意:如果不想进行大小写敏感的比较,可使用caseInsensitiveCompare:方法。在这个例子中,使用caseInsensitiveCompare比较字符串对象@"string"和@"STRING"会相等。
一些方法需要指定一个范围确定子字符串,包括开始索引数和字符数,索引数以0开始,因此,使用数字对{0,3}指定字符串中的前三个字符。NSString类(和其他的Foundation类)的一些方法中,使用了一些特殊的数据类型NSRange创建范围对象。实际上,它是结构的typedef定义,包含location和length两个成员,下面是包含这个数据类型的一些基本字符串操作:
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str1 = @"This is string A"; NSString *str2 = @"This is string B"; NSString *res; NSRange subRange; //从字符串中提取前三个字符 res = [str1 substringToIndex: 3]; NSLog(@"First 3 chars of str1 : %@", res); //提取从引索5开始直到结尾的字符串 res = [str1 substringFromIndex: 5]; NSLog(@"Chars from index 5 of str1 : %@",res); //提取从引索8开始到引索13的子字符串(6个字符) res = [[str1 substringFromIndex: 8] substringToIndex: 6]; NSLog(@"Chars from index 8 through 13: %@", res); //更简单的方法 res = [str1 substringWithRange: NSMakeRange(8, 6)]; NSLog(@"Chars from index 8 through 13: %@", res); //从另一个字符串中查找一个字符串 subRange = [str1 rangeOfString: @"string A"]; NSLog(@"String is at index %lu, length is %lu", subRange.location, subRange.length); subRange = [str1 rangeOfString: @"string B"]; if(subRange.location == NSNotFound) NSLog(@"String not found"); else NSLog(@"String is at index %lu, length is %lu", subRange.location, subRange.length); } return 0; }
substringToIndex: 方法创建了一个子字符串,包括首字符到指定的索引数,但不包括这个字符。因为索引数是从0开始的,所以参数3表示从字符串中提取字符0、1和2,并返回结果字符串对象,对于所有采用索引数作为参数的字符串方法,如果提供的索引数对该字符串无效,就会获得Range or index out of bounds的出错消息。
substringFromIndex:方法返回了一个字符串,它从接收者指定的索引字符开始,直到字符串的结尾。
表达式
res = [[str1 substringFromIndex: 8] substringToIndex: 6];
显示了如何结合这两个方法。
要在另一个字符串中查找一个字符串,可以使用rangeOfString:方法。如果在接收者中找到指定的字符串,则返回的范围是找到的精确位置。然而如果没有找到这个字符串,则返回范围的location成员被设置为NSNotFound。注意:subRange不是对象变量,而是一个结构变量(并且程序中的subRange声明不包括星号,这通常意味着不是在处理一个对象,不过id类型是一个例外)。
5.可变字符串
NSMutableString类可以用来创建可以更改字符串的字符串对象。因为是NSString类的子类,所以可以使用NSString类的所有方法。以下是处理程序中可变字符串的几种方式:
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str1 = @"This is string A"; NSString *search, *replace; NSMutableString *mstr; NSRange substr; //从不可变字符中创建可变字符 mstr = [NSMutableString stringWithString: str1]; NSLog(@"%@", mstr); //插入字符 [mstr insertString: @" mutable" atIndex: 7]; NSLog(@"%@", mstr); //插入末尾进行有效拼接 [mstr insertString:@" and string B" atIndex: [mstr length]]; NSLog(@"%@", mstr); //直接使用appendString [mstr appendString: @" and string C"]; NSLog(@"%@", mstr); //查找然后将其删除 substr = [mstr rangeOfString: @"string B and "]; if(substr.location != NSNotFound){ [mstr deleteCharactersInRange: substr]; NSLog(@"%@", mstr); } //直接设置为可变的字符串 [mstr setString: @"This is string A"]; NSLog(@"%@", mstr); //替换一些字符 [mstr replaceCharactersInRange:NSMakeRange(8, 8) withString: @"a mutable string"]; NSLog(@"%@", mstr); //查找和替换 search = @"This is"; replace = @"An example of"; substr = [mstr rangeOfString: search]; if(substr.location != NSNotFound){ [mstr replaceCharactersInRange: substr withString: replace]; NSLog(@"%@", mstr); } //查找和替换所有的匹配项 search = @"a"; replace = @"X"; substr = [mstr rangeOfString: search]; while(substr.location != NSNotFound){ [mstr replaceCharactersInRange: substr withString:replace]; substr = [mstr rangeOfString: search]; } NSLog(@"%@", mstr); } return 0; }