"OC基础"这个分类的文章是我在自学Stephen G.Kochan的《Objective-C程序设计第6版》过程中的笔记。
1、有时要将一些数字数据类型的值当做对象来使用,那么就可以使用NSNumber类,它会根据这些数据的类型创建对象。
2、注意以下代码段:
...
NSNumber *num1, *num2, *num3; //NSNumber是类
NSInteger myInt; //NSInteger是一个typedef定义过的基本数据类型,所以不用*
num1 = [NSNumber numberWithInteger: 100];
myInt = [num1 integerValue];
NSLog(@”%li”, (long) myInt); //输出:100
num2 = [NSNumber numberWithLong: 0xabcde];
NSLog(@”%lx”, [num2 longValue]); //输出:abcde,不能直接输出NSNumber对象
num2 = [NSNumber numberWithChar: ‘X’];
NSLog(@”%c”, [num2 charValue]); //输出:X
num3 = [NSNumber numberWithFloat: 100.00];
NSLog(@”%g”, num3 floatValue); //输出:100
num2 = [NSNumber numberWithDouble: 12345e+15];
NSLog(@”%lg”, num1 doubleNumber); //输出:12345e+15
NSLog(@”%li”, (long)[num2 integerValue]); //这里的输出值将会是一个大负数
if([num1 isEqualToNumber: num3] == YES)
NSLog(@”Numbers are equal.”);
else
NSLog(@”Numbers are not equal.”); //输出:Numbers are equal.
if([num1 compare: num2] == NSOederedAscending)
NSLog(@”First number id less than second.”); //输出:First number id less than second.
...
以上代码段用到了NSNumber类的一些基本方法。可以注意到以下几点:
(1)、NSInteger是一个typedef定义过的基本数据类型,不是类,所以不用*;
(2)、NSNumber类的创建方法都是numberWith后面加上数据类型,初始化方法都是initWith后面加上数据类型,检索实例方法都是数据类型后面加上Value;
(3)、对某个NSNumber类的对象赋一个double类型的值后,使用integerValue方法去检索读取它,出来的值却是一个错误的大负数。所以在NSNumber里存储了一个某类型的值之后,也要用和这个类型匹配的获取方法去读取;
(4)、使用isEqualsToNumber:方法比较两个NSNumber对象的数值,返回值是BOOL类型。使用compare:方法判断两个NSNumber对象的值的大小,则如果第一个值小于第二个值时返回NSOrderedAscending,第一个值等于第二个值时返回NSOrderedSame,第一个值小于第二个值时返回NSOrderedDescending。
3、如果使用alloc:和initWithXxx:为NSNumber类的对象赋值,那么之后就不可以再用initWithXxx:方法修改它的值,只能使用numberWithXxx:方法来修改。
4、NumberWithInt: 方法和NumberWithInteger: 方法的关系:
(1)、两个方法都会返回一个NSNumber类对象;
(2)、NumberWithInt: 方法的参数是一个int类型的值,而NumberWithInteger: 方法的参数是一个NSInteger类型的对象;
(3)、直接写一个数字,XCode也能把它当成NSInteger对象来处理。
5、可以直接使用@加上数字的方式给NSNumber对象赋值,比如:
num1 = @100;
但是如果@后面跟的是变量或者表达式,就要加上括号。
6、C语言样式的字符串是由char字符组成,而NSString对象则由unichar字符组成。
7、使用@“”即可创建一个字符串对象。
8、NSConstantString类是字符串对象NSString类的子类。
9、可以在NSLog函数中使用%@来显示NSString对象,而且也可以显示其他一些对象。
10、事实上可以使用%@来显示数组、字典、集合或者其他任何对象的全部内容,其实NSLog函数使用%@显示内容,是通过调用description方法来处理的,你只需要重载description这个方法,就可以随心所欲地显示你自定义的类的对象。重载模板如下:
-(NSString *) description {
return (NSString stringWithFormat: @”%...”, ...);
}
%后面第一个省略号写上你要显示的自定义类的实例变量或者其他内容的原本格式显示符(比如int要写i),第二个省略号写上自定义类的实例变量或者其他内容。那么就可以直接使用NSLog(@”%@”,xClass)来显示这个对象了(xClass是对象名)。
其实NSLog也重载了description方法,NSLog默认只是仅仅显示类名和该对象在内存中的地址。
11、使用@“”创建字符串对象时,创建的是一个内容不可更改的对象,即是不可变对象。可变的字符串类型是使用NSMutableString类来处理的。
12、NSString类的几个主要方法:
...
NSString *str1 = @”abcdSERF”;
NSString *str2 = @”WEsdfRF”;
NSString *str3;
NSComparisonResult res; //用来存储compare方法的结果;
NSLog(@"length of str1 is: %lu", [str1 length]); //输出结果是8
str3 = [NSString stringWithString: str1];
NSLog(@"%@",str3); //输出结果是abcdSERF
str2 = [str1 stringByAppendingString: str2];
NSLog(@"%@", str2); //输出结果是abcdSERFWEsdfRF
if([str1 isEqualToString: str3] == YES)
NSLog(@"Equal. "); //输出结果是Equal.
else
NSLog(@"Not equal. ");
res = [str1 compare: str2];
if(res == NSOrderedAscending)
NSLog(@"小于");
else if(res == NSOrderedSame)
NSLog(@"等于");
else //NSOrderedDescending
NSLog(@"大于");
str3 = [str1 uppercaseString];
NSLog(@"%s", [str3 UTF8String]); // 输出结果是ABCDSERF
str3 = [str1 lowercaseString];
NSLog(@"%@", str3); //输出结果是abcdserf
NSLog(@"%@", str1); //输出结果是abcdSERF
...
注意以下几点:
(1)、理解常用的几个NSString类的方法;
(2)、NSComparisonResult类的对象是用来存储compare方法返回的值的,返回值是一个类对象,当比较的两个值中第一个值大于第二个值返回NSOrderedDescending,第一个值等于第二个值返回NSOrderedSame,第一个值小于于第二个值返回NSOrderedAscending;
(3)、使用compare:方法比较两个字符串的大小,会逐个比较字符,其中比较的依据是:汉字大于字母,小写字母大于大写字母(z大于a,Z大于A),大写字母大于数字(9大于0),数字大于空格;
(4)、如果要忽略大小写进行比较,使用caseInsenditiveCompare:方法;
(5)、使用stringWithString:方法复制对象和使用等于号复制是不同的,使用等于号只是复制了指针,使用stringWithString:方法是内容的复制,复制值与被复制值指向的是两个不同的地址;
(6)、使用stringByAppendingString:方法拼接字符串后,并没有改变拼接的两个字符串的值,而是返回一个新的字符串对象;但是可以将返回值直接赋给其中一个拼接对象。
13、理解以下代码段:
...
NSString *str1 = @"This is string A";
NSString *str2 = @"This is string B";
NSString *res;
NSRange subRange;
res = [str1 substringToIndex: 3];
NSLog(@"%@", res); //输出结果是:Thi (前3位)
res = [str1 substringFromIndex: 5];
NSLog(@"%@", res); //输出结果是:is string A(没有空格,从i开始)
res = [str1 substringWithRange: NSMakeRange(8,6)];
NSLog(@"%@", res); //输出结果是: string(没有空格,从s开始,取6个)
subRange = [str1 rangeOfString: @"string A"];
NSLog(@"String is at index %lu, length is %lu", subRange.location, subRange.length);
//输出结果是:String is at index 8, length is 8
subRange = [str1 rangeOfString: @"string B"];
if(subRange.location == NSNotFound)
NSLog(@"没有");
else
...
注意以下几点:
(1)、substringToIndex:方法计算的是个数,后面跟的参数是多少,返回的值就是几位;
(2)、substringFromIndex: 方法、substringWithRange:方法和rangeOfString:方法取的是字符的索引,索引是以0开始的,以此类推;
(3)、rangeOfString:方法返回的值是NSRange类的对象,这个对象包括一个位置属性location和长度属性length。如果没有查找到对应字符串,则返回值对象的location属性为“NSNotFound”;
(4)、对于采用索引数作为参数的字符串方法,如果提供的索引数对字符串无效,则编译器会报Range or index out of bounds的出错消息;
(5)、NSRange变量不是类对象,而是一个结构变量,所以声明的时候不需要*(类对象声明的时候一般都要*,不过id类型是个例外);
14、NSMutableString类可以用来创建可变字符串,这个类是NSString类的子类。
15、不可变字符串对象在给它赋新值的时候,其实是改变了它的指针,从旧的地址改成了新的地址,新的地址会有新的内容,但是旧的地址还存着旧的内容;可变字符串对象可以直接修改存储的内容。
16、理解以下代码段:
...
NSString *str1 = @"This is string A";
NSString *search, *repleace;
NSMutableString *mstr;
NSRange substr;
mstr = [NSMutableString stringWithString: str1];
NSLog(@"%@", mstr); //mstr获得了str1的值
[mstr insertString: @" mutable" atIndex: 7]; //注意mutable前有个空格
NSLog(@"%@", mstr); //输出了This is mutable string A,使用的也是索引数
//即是index写了几,插入的字符串第一个字符的索引就是几
[mstr insertString: @" and string B" atIndex: [mstr length]];
NSLog(@"%@", mstr); //输出了This is mutable string A and string B
[mstr appendString: @" and string C"];
NSLog(@"%@", mstr); //输出了This is mutable string A and string B and string C
[mstr deleteCharactersInRange: NSMakeRange (16, 13)];
NSLog(@"%@", mstr); //删除,输出了This is mutable string B and string C
substr = [mstr rangeOfString: @"string B and "]; //记住NSRange是一个记录位置的集合
if(substr.location != NSNotFound) { //注意.location
[mstr deleteCharactersInRange: substr]; //所以substr和NSMakeRange是一样的
NSLog(@"%@", mstr); //输出了This is mutable string C
}
[mstr setString: @"This is string A"];
NSLog(@"%@", mstr); //输出This is string A
//说明可以直接修改mstr的内容
[mstr replaceCharactersInRange: NSMakeRange(8,8) withString: @"a mutable string"];
NSLog(@"%@", mstr); //输出This is a mutable string
search = @"This is";
replace = @"An example of";
substr = [mstr rangeOfString: search];
if(substr.location != NSNotFound) {
[mstr replaceCharactersInRange: substr withString: replace]; //结合了前两个例子
NSLog(@"%@", mstr); //输出了An example of a mutable string
}
search = @"a";
replace = @"X";
substr = [mstr rangeOfString: search];
while(substr.location != NSNotFound) {
[mstr replaceCharactersInRange: substr withString: replace]; //结合了前两个例子
substr = [mstr rangeOfString: search];//因为每次只会查找到一个,只会删除一个,
//所以要循环
}
NSLog(@"%@", mstr); //输出了An exXmple of X mutXble string
注意以下几点:
(1)、可变字符串对象可以使用方法直接修改字符串对象的值,没有返回值。不可变字符串对象是用方法修改后返回再赋值给字符串对象;
(2)、可变字符串可以使用setString:方法直接设置内容;
(3)、最后那一个循环替换的方法,可以使用以下方法来替换:
[mstr replaceOccurrencesOfString: search
withString: replace
options: nil //这个参数是NSStringCompareOptions
range: NSMakeRange(0, [mstr length] ) ];