1.NSString
字符串的初始化
NSString *str1 = [[NSString alloc]init];
NSString *str2 = @"abc";
字符串和基本数据类型转化
基础数据类型 -> 字符串
NSString *str3 = [NSString stringWithFormat:@"%d",1] ;
NSString *str4 = [NSString stringWithFormat:@"%f",1.5];
字符串 ->基础数据类型
int a = str3.intValue;
float b = str4.floatValue;
字符串比较
NSString *str1 = [NSString stringWithFormat:@"%@",@"abc"];
NSString *str2 = [NSString stringWithFormat:@"%@",@"abc"];
NSString *str3 = [NSString stringWithFormat:@"%@",@"123"];
if ([str1 isEqualToString:str2]) {
NSLog(@"字符串相等");
}
if (![str1 isEqualToString:str3]) {
NSLog(@"字符串不相等");
}
注意:if ([str1 == str2])不用这种写法,==意味着内容和内存地址都要相等。
字符串大小写
NSString *str1 = @"abcDefg";
NSLog(@"%@",[str1 lowercaseString]); // 全部小写abcdefg
NSLog(@"%@",[str1 uppercaseString]); // 全部大写ABCDEFG
NSLog(@"%@",[str1 capitalizedString]); // 首字母大写Abcdefg
字符串内容索引
NSString *str1 = @"abcdefg";
NSString *str2 = @"cde";
NSRange range; //结构体,描述的是字符串的长度和位置
range = [str1 rangeOfString:str2]; //位置从0开始算
NSLog(@"%lu %lu",(unsigned long)range.length,(unsigned long)range.location);
输出结果:3 2
字符串的位置索引
NSString *str1 = @"abcdefg";
NSRange range;
range.length = 2;
range.location = 3;
NSString *str2 = [str1 substringWithRange:range];
NSLog(@"%@",str2);
输出结果:de
字符串增删改查
NSString *str1 = @"abc";
NSString *str2 = [str1 stringByAppendingString:@"123"]; //字符串追加
NSString *str3 = [str2 stringByAppendingFormat:@"%d",999]; //字符串追加
NSString *str4 = [str3 stringByReplacingOccurrencesOfString:@"c123" withString:@"aa"]; //字符串 修改
NSString *str5 = [str3 stringByReplacingOccurrencesOfString:@"999" withString:@""]; //字符串删除
可变字符串
NSMutableString *str6 = [[NSMutableString alloc]init];
[str6 appendString:@"abc"];
[str6 appendString:@"123"];
[str6 insertString:@"hhh" atIndex:3];
[str6 appendFormat:@"%f",4.5];
NSLog(@"%@",str6);
输出结果:abchhh1234.500000
字符串检查
if ([str1 containsString:@"imooc"]) {
NSLog(@"包含慕课网");
}
if ([str1 hasPrefix:@"http"]) {
NSLog(@"http");
}
if ([str1 hasSuffix:@"com"]) {
NSLog(@"com");
}
常用技巧
NSString *str1 = @" abc edf ";
NSLog(@"str1 = %@",str1);
NSString *str2 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];//首尾两端去空格
NSLog(@"str2 = %@",str2);
NSLog(@"%d %d",str1.length,str2.length);
输出结果:str1 = abc edf
str2 = abc edf
9 7
2.数组NSArray
OC中全局NSMutableArray对象不能addObject局部对象!!!
解决方法https://blog.csdn.net/ttf1993/article/details/46470897
数组的初始化
NSArray *array1 = [[NSArray alloc]init];
NSArray *array2 = [[NSArray alloc]initWithObjects:@"abc",@"123",@"d",nil];
NSArray *array3 = @[@"333",@"abc"];
增删改查
//查:位置索引
NSString *item1 = [array2 firstObject];
NSString *item2 = [array2 lastObject];
NSString *item3 = [array2 objectAtIndex:1];
NSLog(@"%@ %@ %@",item1,item2,item3);
//查:内容索引
NSInteger index1 = [array2 indexOfObject:@"d"];
NSLog(@"index = %ld",(long)index1);
//查:长度
NSLog(@"count = %lu",(unsigned long)array2.count);
//查:是否包含
NSLog(@"%d %d",[array2 containsObject:@"123"],[array2 containsObject:@"kj"]);
//增:
NSMutableArray *array1 = [[NSMutableArray alloc]init];
NSMutableArray *array2 = [[NSMutableArray alloc]initWithObjects:@"abc",@"123",@"ff", nil];
[array2 addObject:@"456"];
[array2 insertObject:@"00" atIndex:2];
//删除 修改
[array2 removeLastObject];
[array2 removeObject:@"00"];
[array2 removeObjectAtIndex:1];
[array2 removeAllObjects];
数组遍历和快速枚举:含中文
NSArray *array1 = @[@"abc",@"123",@"你好"];//数组中直接存储中文输出会乱码
NSLog(@"%@",array1);
for (int i = 0; i < array1.count; i++) {//出现中文需要打印可以使用for循环
NSString *item = [array1 objectAtIndex:i];
NSLog(@"item = %@",item);
}
for (NSString *item in array1) {//出现中文也可以使用快速枚举
NSLog(@"item = %@",item);
}
字符串数组相互转化
//NSString <-> NSArray
NSString *str = @"1@2@3@4@5";
NSArray *array1 = [str componentsSeparatedByString:@"@"];//表明按照@进行划分
NSLog(@"%@",array1);
NSMutableString *str1 = [[NSMutableString alloc]init];
for (NSString *item in array1) {
[str1 appendFormat:@"%@@",item]; //第二个@只是一种格式,之前就是用这个@进行划分的
}
NSLog(@"%@",str1);
可变数组的使用
NSArray *array1 = @[@"123",@"abc"];
// NSMutableArray *array2 = array1; //NSArray -> NSMutableArray不要用这种方式
NSMutableArray *array2 = [[NSMutableArray alloc]initWithArray:array1]; //用这种
NSArray *array3 = array2; //NSMutableArray -> NSArray可以直接用这种
3.字典NSDictionary
1 vs 1
key:唯一
无顺序
字典初始化
NSDictionary *dict1 = [[NSDictionary alloc]init];
NSDictionary *dict2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"2.5",@"apple",@"2.2",@"orange", nil]; //这种是先value,后面接key
NSDictionary *dict3 = @{@"1.64":@"beijing",@"1.19":@"tianjin"}; //这种是key:value
增删改查
//查:key索引 一般通过key查value,因为key唯一而value不唯一
NSString *str1 = [dict2 valueForKey:@"apple"];
NSLog(@"%@",str1);
//查所有key 所有value,查了之后会以数组的形式返回
NSArray *array1 = [dict2 allKeys];
NSArray *array2 = [dict2 allValues];
NSLog(@"%@ %@",array1,array2);
//查:遍历 快速枚举
for (int i = 0; i < array1.count; i++) { //value的枚举
NSString *item = [dict2 valueForKey:[array1 objectAtIndex:i]];
NSLog(@"item = %@",item);
}
for (NSString *item in dict2) { //key的枚举
NSLog(@"item = %@",item);
}
//查:字典数组混合遍历 没有先后顺序,顺序可能不同,对于内容不统一的有字符串有数组的可以采用id形式
NSArray *array3 = @[@"abc",@"123"];
NSDictionary *dict4 = [[NSDictionary alloc]initWithObjectsAndKeys:@"value1",@"keya",@"value2",@"keyb",array3,@"keyc", nil];
NSLog(@"%@",dict4);
for (int i = 0; i < [dict4 allKeys].count; i++) {
id item = [dict4 valueForKey:[[dict4 allKeys] objectAtIndex:i]];
NSLog(@"item = %@",item);
}
//增
NSMutableDictionary *mdict1 = [[NSMutableDictionary alloc]init];
[mdict1 setValue:@"3" forKey:@"apple"];
[mdict1 setValue:@"2.5" forKey:@"banana"];
NSLog(@"%@",mdict1);
//改
[mdict1 setValue:@"8" forKey:@"apple"];
NSLog(@"%@",mdict1);
//删
[mdict1 removeObjectForKey:@"apple"];
NSLog(@"%@",mdict1);
[mdict1 removeAllObjects];
NSLog(@"%@",mdict1);
//中文
NSDictionary *dict5 = @{@"北京":@"首都"};
NSLog(@"%@",dict5); //乱码
NSString *item = [dict5 valueForKey:@"北京"];
NSLog(@"%@",item); //不乱码
4.iOS内存管理(非常重要,面试时候可能会考)
内存,指针,堆和栈的基本概念
存储器,存储器通常用来存储程序和数据,电脑的存储空间=内存条+硬盘,我们通常所说的电脑的内存就是电脑的内存条,而手机的内存是手机的内存条+外部存储空间
堆和栈的区别:堆由程序员手动分配和释放,栈由操作系统分配和释放,比如说一些局部变量可能存储在栈中,堆:先进先出,栈:先进后出
iOS内存管理机制
电脑的硬盘相当于手机的存储空间,电脑的内存条相当于手机的内存。应用下载后会占用手机的存储空间,而应用未启动的时候不占用内存空间,启动之后才会占用内存。
为什么要进行内存管理及哪些需要内存管理?①所有继承NSObject的子类都需要进行内存管理。 ②使用其他语言申请的内存空间也需要进行内存管理,比如c 或c++进行混合编程。 ③对于int,BOOL,char这种基础的数据类型不需要进行内存管理。 ④内存警告:如果占用太多内存,ios系统可能直接把应用kill掉
对象存储的基本结构:分两个部分:①引用计数器:是一个整数,表示对象被引用的次数,每一个OC对象的引用计数器都包含了4个字节 ②除引用计数器之外的部分,包含类的指针,索引等
引用计数器的作用:
引用计数器几个原则:①引用计数器初始值为0,所有的对象第一次创建的时候,注意:只是创建,而未进行其他操作,这个时候引用计数器为0 ②如果创建同时对它进行一些操作如alloc new copy 引用计数器+1 ,init只是初始化一些属性,不加1 ③引用计数器为0内存释放 ④retain引用计数器+1 ⑤release的时候 引用计数器-1 ⑥如果想获取引用计数器的值,可以通过retainCount,不过一般使用较少
对象被销毁原则:①引用计数器为0 ②对象被销毁调用dealloc,不要主动调用dealloc方法,这个方法是被动调用的 ③如果坚持使用这块已经无法使用的内存,就可能造成野指针:指向了一个不可用的内存空间:崩溃 ④空指针:表示这个指针指向的内存为空,但它仍然合法,只是无法使用
ARC下内存管理
如果没有强指针指向,那么对象就会被销毁。所有的指针(我们没有特殊定义的)都是强指针。
-(void)dealloc{
NSLog(@"我被释放了");
}
//Person *p1 = [[Person alloc]init];
//NSLog(@"xx");
// xx-》我被释放了
//Person *p1 = [[Person alloc]init];
//p1 = nil;
//NSLog(@"xx");
// 我被释放了->xx
//Person *p1 = [[Person alloc]init];
//Person *p2 = p1;
//p1 = nil;
//NSLog(@"xx");
// xx-》我被释放了
内存自动释放池@autoreleasepool
概念:是oc中一种内存自动回收机制,自动释放池执行完的时候,池里的对象会做一次release
Runtime的理解(!重要)
Runtime概念:Runtime简称运行时。就是在系统运行的时候的一些机制,其中最主要的是消息机制。
[person1 dosomething];
消息机制
person1_msgSend(obj,@selector(dosomething));
①将正常调用的方法翻译成这种消息发送。 ②可以通过obj的isa指针,找到class ③在cache中寻找dosomething方法是否存在,如果没有找到执行④ ④在method_list中找,在方法列表中找到之后,它会执行这个方法,然后把这个方法缓存到本地的cache中
Runtime使用的场景:①程序运行过程中,动态地为程序添加(修改)某些方法和属性 ②遍历类的所有方法和属性
RunLoop的理解
RunLoop就是一个事件处理的循环,用来不停的调动工作以及处理输入事件。使用RunLoop的目的就是节省CPU效率,使线程在有工作的时候忙于工作,而没工作的时候就处于休眠状态
不停地接收数据:RunLoop核心价值
5.深拷贝 浅拷贝
浅拷贝:他们指向的内存空间一致,简单地copy指针,数据不独立,如果修改了A1,A2也会跟着改变。当我们通过A1对这片内存空间进行释放的时候,A2指向的内存也不可用了
深拷贝:开辟一片新的内存空间,拷贝内容,A1,A2指向不同的内存空间,当我们通过A1对这片内存空间进行释放的时候,对A2指向的内存没有任何影响,所以释放对象的时候使用深拷贝
对象的快速拷贝
//main.m
Person *p1 = [[Person alloc]init];
p1.name = @"Robin";
Person *p2 = [p1 copy];
NSLog(@"%@",p2.name);
NSLog(@"%@ %@",p1,p2); //输出的内存空间不同,是深拷贝
//Person.h
@property(nonatomic,copy) NSString *name;
//Person.m
-(id)copyWithZone:(NSZone*)zone{
//创建一个新的内存空间,并且将原来内存空间的内容拷贝一份
Person *copy = [[[self class]allocWithZone:zone] init];
copy.name = [self.name copyWithZone:zone];
return copy;
}
可变地址空间和不可变地址空间的转化
//不可变到可变 copy:只复制内容 mutableCopy:修改地址
NSString *str = @"Hello";
NSMutableString *mstr = [str copy];
NSMutableString *mstr2 = [str mutableCopy];
NSLog(@"%@ %@ %@",str,mstr,mstr2);
NSLog(@"%p %p %p",str,mstr,mstr2); //%p是打印地址,str mstr地址相同,mstr2地址不同
//不可变到不可变 copy:只复制内容 mutableCopy:修改地址
NSString *str = @"Hello";
NSString *mstr = [str copy];
NSString *mstr2 = [str mutableCopy];
NSLog(@"%@ %@ %@",str,mstr,mstr2);
NSLog(@"%p %p %p",str,mstr,mstr2); //%p是打印地址,str mstr地址相同,mstr2地址不同
//可变到不可变 copy:只复制内容 mutableCopy:修改地址
NSMutableString *str = @"Hello";
NSString *mstr = [str copy];
NSString *mstr2 = [str mutableCopy];
NSLog(@"%@ %@ %@",str,mstr,mstr2);
NSLog(@"%p %p %p",str,mstr,mstr2); //%p是打印地址,str mstr地址相同,mstr2地址不同
//可变到可变 copy:只复制内容 mutableCopy:修改地址
NSMutableString *str = @"Hello";
NSMutableString *mstr = [str copy];
NSMutableString *mstr2 = [str mutableCopy];
NSLog(@"%@ %@ %@",str,mstr,mstr2);
NSLog(@"%p %p %p",str,mstr,mstr2); //%p是打印地址,str mstr地址相同,mstr2地址不同
6.谓词
//对数组中的元素进行过滤
NSArray *array1 = [[NSArray alloc]initWithObjects:@"ios",@"android",@"wp", nil];
//1.创建一个谓词对象 2.指定过滤条件 3.过滤条件应用到对象上
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF == 'android'"]; //使用单引号的原因是外面有双引号
NSArray *array2 = [array1 filteredArrayUsingPredicate:pre1];
for (NSString *item in array2) {
NSLog(@"item = %@",item);
}
//逻辑判断
NSString *num1 = [[NSString alloc]initWithFormat:@"%d",3];
NSString *num2 = [[NSString alloc]initWithFormat:@"%d",15];
NSArray *array1 = [NSArray arrayWithObjects:num1,num2, nil];
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF.intValue > 10"];
NSArray *array2 = [array1 filteredArrayUsingPredicate:pre1];//返回值:数组array 参数:谓词Predicate
for (NSString *item in array2) {
NSLog(@"item = %@",item);
}
//关键词的使用 判断数组中是否包含某个元素
NSArray *array1 = [[NSArray alloc]initWithObjects:@"abc",@"def", nil];
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",@"def"];
NSArray *array2 = [array1 filteredArrayUsingPredicate:pre1];
for (NSString *item in array2) {
NSLog(@"item = %@",item);
//注:输出结果为item = def,如果@"SELF CONTAINS %@",@"def"改为@"SELF CONTAINS %@",@"de",输出结果不变,仍是item = def
//CONTAINS:检查是否包含某个内容
}
//过滤对象
Person *person1 = [[Person alloc]init];
person1.age = 10;
Person *person2 = [[Person alloc]init];
person2.age = 20;
NSMutableArray *array1 = [[NSMutableArray alloc]initWithObjects:person1,person2, nil];
NSLog(@"%p %p",person1,person2);
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"age == %d",10];
NSArray *array2 = [array1 filteredArrayUsingPredicate:pre1];//返回值:数组array 参数:谓词Predicate
for (Person *p in array2) {
NSLog(@"%p",p);
}