第十三章主要讲解C语言的语法,书中作者不提倡第一次阅读本书时阅读,故略过。
第十四章介绍Foundation框架,内容比较少,也就此略过。
Part 1. 数字对象
基本的数据类型不是对象,因此不能给他们发信息。但是有的时候需要将这些值作为对象使用:NSArry创建的数组存储的值必须是对象,因此数据类型无法直接存储到数组中,需要NSNumber类,依据数据的类型创建对象。
NSNumber类:每种基本数据类型,NSNumber的类方法都能为它创建一个NSNumber对象。
NSNumber *myNumber, *floatNumber, *intNumber; //NSNumber对象
NSInteger myInt; //NSInteger:基本数据类型的typedef(64位long或者32为int)
//创建integer 整型
intNumber = [NSNumber numberWithInteger:100];
myInt = [intNumber integerValue];//获取存储在intNumber中的整型值
NSLog(@"%li", (long)myInt); //将myInt转换为long型
//创建long 型值
myNumber = [NSNumber numberWithLong:0xabcdf];
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");
//相等:NSOrderdSame
//大于:NSOrderdDescending
-
注意:不能修改前面创建的NSNumber的值:所有数字对象都必须是新创建的。
- 对NSNumber类调用numberWith方法
- 对alloc方法的结果调用initWith方法
通过@表达式创建数字对象
NSNumber *myNumber, *floatNumber, *intNumber;
NSInteger myInt;
//整型 integer
intNumber = @100;
myInt = [intNumber integerValue];
NSLog(@"%li", (long) myInt);
//长整型long value
myNumber = @0xabcdefL;
NSLog(@"%lx", [myNumber longValue]);
myNumber = @'X';
NSLog(@"%c", [myNumber charValue]);
//浮点型
floatNumber = @100.0f;
NSLog(@"%g", [floatNumber floatValue]);
Part 2. 字符串对象
Part 2.1 NSLog函数
//常量字符串对象 Programming is fun 被赋值给NSString变量str
NSString *str = @"Programming is fun";
NSLog(@"%@",str);
Part 2.2 可变对象与不可变对象
- 处理不可变对象
NSString *str1 = @"This is string A"; //常量字符串对象 指向了内存中的某处字符串对象
NSString *str2 = @"This is string B"; //常量字符串
NSString *res;
NSComparisonResult compareResult; //保存结果
//将一个字符串赋复制到另一个字符串
res = [NSString stringWithString:str1]; //str1 赋值给res,字符串内容的复制,产生新的字符串,str1和res指向两个不同的字符串对象;而res=str1:同一对象的另一个引用
//将一个字符串复制到另一个字符串的末尾
str2 = [str1 stringByAppendingString:str2]; //产生新的字符串对象,原字符串对象str1和str2没有被更改:因为是不可变字符串对象
//将字符串转换为大写
res = [str1 uppercaseString]; //res指向新字符串对象(大写),str1仍然指向原来的字符串对象
//字符串转换为小写
res = [str1 lowercaseString]; //原来的大写字符不再被引用。小写字符串的引用存在res中
NSString *str1 = @"This is string A";
NSString *str2 = @"This is string B";
NSString *res;
NSRange subRange;//subRange是结构变量
//从字符串中提取前三个字符
res = [str1 substringToIndex:3];//创建一个子字符串,首字符到指定的索引数。0,1,2
NSLog(@"First 3 chars of str1: %@", res);
//提取从索引5开始直到结尾的子字符串
res = [str1 substringFromIndex:5];//返回一个子字符串,指定索引字符到字符串结尾
//提取从索引8开始到索引13的字符串(6个字符:13-8+1 = 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, lenth is %lu", subRange.location, subRange.length);//结构成员操作符:(.)
- 可变字符串
NSString *str1 = @"This is string A";
NSString *search, *replace;
NSMutableString *mstr; //用来存储在程序执行过程中值可能更改的字符串对象
NSRange substr;
//从不可变字符串创建可变字符串
mstr = [NSMutableString stringWithString: str1]; //返回可变的字符串对象
//插入字符
[mstr insertString:@" mutable" atIndex:7];
//插入末尾进行有效拼接
[mstr insertString:@" and string B" atIndex:[mstr length]];
//直接在末尾添加
[mstr appendString:@" and string C"];
//根据范围范围删除子字符串 从索引数16开始删除13个字符。
[mstr deleteCharactersInRange: NSMakeRange(16, 13)];
//查找然后将其删除
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"];
//查找和替换
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);
Part 3. 数组对象
不可变数组:NSArray
可变数组:NSMutableArray
int main(int argc, const char * argv[]) {
int i;
@autoreleasepool {
//创造和返回一个数组 : arrayWithObjects
NSArray *monthNames = [ NSArray arrayWithObjects:
@"January", @"February", @"March", @"April", @"May",@"June",@"July",@"August",@"September",
@"October", @"November", @"December", nil]; //12个字符串,索引从0开始 0~11
//列出数组中所有的元素
NSLog(@"Month Name");
NSLog(@"===== ====");
for (i = 0; i < 12; ++i)
NSLog(@"%2i %@", i+1, [monthNames objectAtIndex:i]);
// objectAtIndex:索引元素
}
return 0;
}
- 简单创建NSArray对象:
//创建NSArray对象
@[elem1, elem2, ... elemn];
//引用数组元素
array [index]; //等价于:[array objectAtIndex: index]
//将对象的引用存储到数组中
array [index] = object; //等价于:[array setObject: object forIndex: index]
- 创建一个包含各月份的数组
int main(int argc, const char * argv[]) {
int i;
@autoreleasepool {
//创建一个包含各月份名称的数组
NSArray *monthNames = @[ @"January", @"February", @"March", @"April", @"May", @"June", @"July",@"August",@"September",@"October", @"November", @"December"];
//列出数组中的所有元素
NSLog(@"Month Name");
NSLog(@"===== ====");
for (i = 0; i<12; ++i)
{
NSLog(@" %2i %@", i+1, monthNames[i]);
}
}
return 0;
}
- 数字对象的数组
NSMutableArray *numbers = [NSMutableArray array]; //创建空的可变数组对象,数组元素的个数并未指定
int i;
//创建0~9数字的数组
for (i = 0; i < 10; ++i)
{
numbers[i] = @(i); //在数组末尾添加一个对象:[numbers addObject: @(i)];
}
//显示数组每个元素的值
for (i = 0; i < 10; ++i)
{
NSLog(@"%@", numbers[i]);
}
//使带有%@格式的NSLog显示
NSLog(@"====== Using a single NSLog");
NSLog(@"%@", numbers);
- 地址簿实例:
一个可以进行添加,删除,搜索,排序地址卡片(姓名+邮件)的地址簿
AddressCard.h
#import <Foundation/Foundation.h>
@interface AddressCard : NSObject
@property (copy, nonatomic) NSString *name, *email;
-(void) setName:(NSString *) theName andEmail: (NSString *) theEmail; //设置名字,邮件(字符串)
-(void) print; //打印名片
-(NSComparisonResult) compareNames: (id) element;//比较两个字符串
@end
AddressCard.m
#import "AddressCard.h"
@implementation AddressCard
@synthesize name, email;
-(void) setName:(NSString *) theName andEmail: (NSString *) theEmail
{
self.name = theName;
self.email = theEmail;
}
-(NSComparisonResult) compareNames: (id) element
{
return [name compare: [element name]];//两个字符串的比较,返回比较结果
}
-(void) print
{
NSLog(@"==============================");
NSLog(@"| |");
NSLog(@"| %-31s |", [name UTF8String]);
NSLog(@"| %-31s |", [email UTF8String]);
NSLog(@"| |");
NSLog(@"==============================");
}
@end
AddressBook.h
#import <Foundation/Foundation.h>
#import "AddressCard.h"
@interface AddressBook : NSObject
@property (nonatomic, copy) NSString *bookName;
@property (nonatomic, strong) NSMutableArray *book;
-(instancetype) initWithName: (NSString *) name; //设置初始数组
-(void) addCard: (AddressCard *) theCard; //向地址簿添加名片
-(void) removeCard: (AddressCard *) theCard;//向地址簿移除名片
-(AddressCard *) lookup: (NSString *) theName; //查找名片
-(int) entries; //获取名片的数量
-(void) list; //显示地址簿的全部内容
-(void) sort; //排序地址簿中的名片
@end
AddressBook.m
#import "AddressBook.h"
@implementation AddressBook
@synthesize bookName, book;
//设置addressbook的名称和一个空的addressbook
-(instancetype) initWithName:(NSString *)name //返回值类型定义为:一般的对象类型
{
if (self) {
bookName = [ NSString stringWithString:name ];//将方法参数传递过来的字符串复制一份存储在实例变量bookName中
book = [ NSMutableArray array ];//再创建一个空的NSMutableArray对象赋值给book
}
return self;
}
-(instancetype) init
{
return [self initWithName:@"NoName"];
}
-(void) addCard:(AddressCard *)theCard //将AdrressCard作为参数,添加到地址簿中
{
[book addObject: theCard];
}
-(void) removeCard: (AddressCard *) theCard
{
[book removeObjectIdenticalTo: theCard];
}
-(int) entries //返回地址簿中存储的地址卡片数目
{
return [book count]; //count方法返回数组元素的个数;
}
-(void) list
{
NSLog(@"========== Contents of: %@ =========", bookName);
for ( AddressCard *theCard in book) //book数组的每个元素序列使用快速枚举技术
NSLog(@"%-20s %-32s", [theCard.name UTF8String],[theCard.email UTF8String]);
NSLog(@"=======================================================");
}
-(void) sort
{
[book sortUsingSelector:@selector(compareNames:)]; //sortUsingSelector:比较数组中的两个元素
}
-(AddressCard *) lookup: (NSString *) theName
{
for (AddressCard *nextCard in book) //快速枚举
if ( [nextCard.name caseInsensitiveCompare: theName] == NSOrderedSame)
return nextCard;
return nil;
}
@end
main:
#import <Foundation/Foundation.h>
#import "AddressBook.h"
#import "AddressCard.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *aName = @"Julia";
NSString *aEmail = @"julia@gmail.com";
NSString *bName = @"Tony";
NSString *bEmail = @"tony@gmail.com";
NSString *cName = @"Stephen";
NSString *cEmail = @"steve@gmail.com";
NSString *dName = @"Jamie";
NSString *dEmail = @"jamie@gmail.com";
AddressCard *card1 = [[AddressCard alloc] init];
AddressCard *card2 = [[AddressCard alloc] init];
AddressCard *card3 = [[AddressCard alloc] init];
AddressCard *card4 = [[AddressCard alloc] init];
//创建一个新的地址簿
AddressBook *myBook = [[AddressBook alloc] initWithName:@"Linda's Address Book " ];
AddressCard *myCard;
//创建四个卡片
[card1 setName:aName andEmail:aEmail];
[card2 setName:bName andEmail:bEmail];
[card3 setName:cName andEmail:cEmail];
[card4 setName:dName andEmail:dEmail];
//将地址卡片添加到地址簿
[myBook addCard:card1];
[myBook addCard:card2];
[myBook addCard:card3];
[myBook addCard:card4];
//列出未排序的地址簿
[myBook list];
//进行排序并在此列出
[myBook sort];
[myBook list];
//通过名字查找一个
NSLog(@"Lookup : Stephen:");
myCard = [myBook lookup: @"Stephen"];
if (myCard != nil) {
[myCard print];
}
else
NSLog(@"Not Found!");
//从电话簿中删除条目
[myBook removeCard:myCard];
[myBook list];
}
return 0;
}
Part 4. 词典对象
- 词典:键—对象对组成的数据集合,通过对象的键从词典中获取对象。和键关联的值可以是任何类型,但不能使nil。
- 词典可以固定,可以可变:动态添加和删除,使用键检索词典,可以枚举内容。
NSMutableDictionary *glossary = [ NSMutableDictionary dictionary];//创建空的可变词典
//存储一个条目在类别中
[glossary setObject:@"A class defined so other classes can inherit from it" forKey:@"abstract class"];
//检索并显示
NSLog(@"abstract class: %@", [glossary objectForKey:@"abstract class"])
//[dict objectForKey: key] 等同于 dict[ key ]
//[dict setObject: object forKey: key] 等同于: dict[key] = object
- 枚举词典
//创建对象-键对的数组
NSDictionary *glossary = [NSDictionary dictionaryWithObjectsAndKeys:
@"A class defined so other classes can inherit from it",
@"abstract class",
@"To implement all the methods defined in a protocol",
@"adopt",
@"Storing an object for later use",
@"achiving",
nil];
for (NSString *key in glossary) //枚举
NSLog(@"%@:%@", key, [glossary objectForKey:key]);
Part 5. 集合对象
- set:单值对象集合
- 可变,不可变
- 搜索,添加,删除集合中的成员,比较两个集合,计算两个集合的交集和并集
NSMutableSet *set1 = [NSMutableSet setWithObjects:
@1, @3, @5, @10, nil];
NSSet *set2 = [NSSet setWithObjects:
@-5, @100, @3, @5, nil];
NSSet *set3 = [NSSet setWithObjects:
@12, @200, @3, nil];
NSLog(@"set1:");
[set1 print];
NSLog(@"set2:");
[set2 print];
//相等性测试
if ([set1 isEqualTo:set2] == YES) {
NSLog(@"set1 equals set2");
} else {
NSLog(@"set1 is not equat to set2");
}
//成员测试
if ([set1 containsObject:@10]) {
NSLog(@"set1 contains 10");
} else {
NSLog(@"set1 does to contain set2");
}
if ([set2 containsObject:@10]) {
NSLog(@"set2 contains 10");
} else {
NSLog(@"set2 does to contain set2");
}
//在可变集合set1中添加和移除对象
[set1 addObject:@4];
[set1 removeObject:@10];
NSLog(@"set1 after adding 4 and removing 10:");
[set1 print];
//获得两个集合的交集
[set1 intersectSet:set2];
NSLog(@"set1 inserct set2: ");
[set1 print];
//获得两个集合的并集
[set1 unionSet:set3];
NSLog(@"set1 union set3: ");
[set1 print];