OC加强-day06

时间:2021-08-25 20:24:38

#program mark - 08 NSMutableDictionary的使用 [掌握]

"/08 NSMutableDictionary的使用/1_练习

"练习

1.小明的身高1米5,体重80KG,年龄10岁,创建可变字典存储这些信息

int main(int argc, const char * argv[]) {

NSMutableDictionary *MxiaomingDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"1.5m",@"height",@"80KG",@"weight",@"10",@"age"

, nil];

NSLog(@"%@",MxiaomingDict);

return 0;

}

2.小明使用的手机是nokia5610,使用的手表是appleWatch,把两个键值对添加到字典

int main(int argc, const char * argv[]) {

NSMutableDictionary *MxiaomingDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"1.5m",@"height",@"80KG",@"weight",@"10",@"age"

, nil];

[MxiaomingDict setObject:@"nokia5610" forKey:@"phone"];

[MxiaomingDict setObject:@"appleWatch" forKey:@"watch"];

NSLog(@"%@",MxiaomingDict);

return 0;

}

3.删除身高和手表的键值对

int main(int argc, const char * argv[]) {

NSMutableDictionary *MxiaomingDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"1.5m",@"height",@"80KG",@"weight",@"10",@"age"

, nil];

[MxiaomingDict setObject:@"nokia5610" forKey:@"phone"];

[MxiaomingDict setObject:@"appleWatch" forKey:@"watch"];

NSLog(@"%@",MxiaomingDict);

[MxiaomingDict removeObjectsForKeys:@[@"height",@"watch"]];

NSLog(@"%@",MxiaomingDict);

return 0;

}

#program mark - 09 字典的持久化 [听懂]

写入到文件

#program mark - 10 集合的内存管理 [掌握]

"复习

1.MRC内存管理的原则

1>每一个OC对象都有一个属性叫引用计数器 retainCount

2>用alloc/new直接创建的 对象retainCount为1

3>只要有新的指针指向一个对象,就应该让对象的retainCount+1  --> [指针  retain];

4>指向对象的指针销毁之前应该让指向的对象的retainCount-1  --> [指针  release];

5>对象的引用计数器为0的时候,操作系统自动回收对象,并顺便调用dealloc.

2.ARC内存管理原则

1>强指针

__strong修饰的指针,一个指针前面什么都不写默认是强指针

2>弱指针

__weak修饰的指针

3>一个对象只要没有强指针指向,立刻就释放掉.

"集合的内存管理

1.什么是集合

OC中字典和数组统称集合

2.MRC

1>把对象放入集合中,对象的retainCount会自动+1

2>集合销毁的时后,对象的retainCount会自动-1

"随堂代码/10 集合的内存管理/1_MRC

int main(int argc, const char * argv[]) {

MKPerson *xiaoyue = [MKPerson new];

NSLog(@"%lu",xiaoyue.retainCount);

//    NSArray *test = @[xiaoyue];

//    NSMutableArray *test = [NSMutableArray arrayWithObject:xiaoyue];

NSDictionary *test = @{@"per":xiaoyue};

NSLog(@"%lu",xiaoyue.retainCount);

[test release];

NSLog(@"%lu",xiaoyue.retainCount);

[xiaoyue release];

return 0;

}

2.ARC

1>ARC下,集合自身的内存管理很特殊,不遵守强指针弱指针原则

"随堂代码/10 集合的内存管理/2_ARC下集合创建自动autorelease

int main(int argc, const char * argv[])

{

{

MKPerson *xiaoyue = [MKPerson new];

NSMutableArray *test = [NSMutableArray arrayWithObject:xiaoyue];

//发现出了作用域集合对象没有销毁,

//如果销毁了,那么xiaoyue指向的对象肯定没有强指针指向了,应该释放,现在没有释放,所以集合肯定没有销毁

}

return 0;

}

2>[记住]

ARC下苹果提供的创建集合的方式内部对集合做了autorelease,为了避免内存泄露,所以尽量把创建集合的代码放到自动释放池中

int main(int argc, const char * argv[])

{

@autoreleasepool{

MKPerson *xiaoyue = [MKPerson new];

NSMutableArray *test = [NSMutableArray arrayWithObject:xiaoyue];

}//代码走到这一行,集合被销毁,集合中存储的xiaoyue指针也被销毁,所以人对象被释放了

return 0;

}

#program mark - 11 NSFileManager的常用方法之判断 [听懂]

NSFileManager: 用来操作磁盘上的文件 文件夹 对他们进行创建,删除,复制,移动...

这个类创建的对象是以单例模式创建的

#program mark - 12 NSFileManager的常用方法之获取信息 [听懂]

判断指定过得文件或文件夹在磁盘上是否真实存在

- (BOOL)fileExistsAtPath:(NSString *)path;

判断指定过得文件或文件夹在磁盘上是否可读

- (BOOL)isReadableFileAtPath:(NSString *)path;

判断指定过得文件或文件夹在磁盘上是否可写

- (BOOL)isWritableFileAtPath:(NSString *)path;

判断指定过得文件或文件夹在磁盘上是否可执行

- (BOOL)isExecutableFileAtPath:(NSString *)path;

判断指定过得文件或文件夹在磁盘上是否可删

- (BOOL)isDeletableFileAtPath:(NSString *)path;

#program mark - 13  NSFileManager的其他方法

#program mark - 14 文件终结者

#program mark - 15 结构体与类的区别

"引入

1.ios开发中每一个控件,都是View,

2.这个view一定有坐标,通过这个坐标可以确定控件在屏幕哪一个位置显示

3.坐标: 包含x轴坐标和y轴坐标

"问题

如何表示一个坐标?

1.结构体

struct Point {

float x;

float y;

};

2.类

@interface Point : NSObject

@property(nonatomic,assign)float x;

@property(nonatomic,assign)float y;

@end

@implementation Point

@end

"问题

到底应该结构体还是类?

1>结构体

只能有属性,不能有方法

结构体变量存储在栈区域-->访问速度稍微比堆区快

2>类

既能有属性又能有方法

实例化对象存储在堆区,速度比栈区稍慢

3>表示坐标

只需要一个x坐标和一个y坐标,不需要方法-->结构体

"结论

1>如果表示的数据类型既有属性又有行为就只能用类

2>如果这个类型属性比较少,又没有行为,就使用结构体

3>一句话,轻量级用结构体 重量级用类

#program mark - 16 CGPoint [掌握]

此知识点的复习见OC加强05视频笔记/16 CGPoint.pdf

"练习

1.创建一个类叫做YYView表示一个视图

2.添加一个结构体属性叫做orign,这个结构体包含x坐标和y坐标

3.创建一个view对象叫做testView,给origin属性赋值为(100,100)

4.打印这个testView的坐标

#program mark - 17 CGSize [掌握]

此知识点的复习见OC加强05视频笔记/17 CGSizet.pdf

"练习

1.在上面练习的基础上给YYView类添加一个属性结构体属性叫做size,这个结构体内包含float类型的高度height和宽度width

2.给testYiew的这个size属性赋值为(100,200)

3.打印testYiew的长度和宽度

#program mark - 18 CGRect

"练习

1.把上面练习的YYView类的orign属性和size属性封装成一个叫做frame的结构体属性

2.修改代码,使得程序能正常运行

#program mark - 19 案例讲解 [了解]

1.ios开发中有一个类ViewController类表示ios应用的一个界面,程序一起动会调用这个对象的viewdidload方法

2.ios开发中有一个类UIKit框架中有一个类叫做UIView,表示一个视图

3.UIView有一个属性叫做frame,是一个CGRect类型的结构体,表示视图的坐标和尺寸

4.UIView有一个属性叫做backgroundColor可以通过赋值符号用[UIColor redColor]设置为红色

5.UIView有一个对象方法叫做addSubView:可以添加一个视图到自己内部

6.ViewController中有一个和屏幕尺寸一样大的UIView类型的属性叫做view

按照上面提示在ios应用下完成需求

1.创建一个UIView对象,坐标是(50,60),尺寸是(100,200),颜色是绿色

2.在模拟器上显示这个对象

#program mark - 20 NSNumber [掌握]

"练习

"随堂代码/20 NSNumber/1_练习

用快速转换的方式把下面常量或者变量添加到不可变数组中存储起来:

int num = 10;

10

11.1f

12.2

'a'

int main(int argc, const char * argv[]) {

int num = 10;

NSArray *arr = @[@(num),@10,@11.1f,@12.2,@'a'];

NSLog(@"%@",arr);

return 0;

}

#program mark - 21NSValue

#program mark - 22 NSDate的基本使用

#program mark - 23 得到日期对象的各个部分

#program mark - 24 字符串的拷贝[重点掌握]

1.字符串深拷贝和浅拷贝的概念

1>浅拷贝

1)OC中的字符串是在堆区或常量区存储的对象

2)这个对象由一个栈区的指针指向

3)把这个字符串对象的指针复制一份,此时有两个指针指向这一个字符串对象,这个过程叫做浅拷贝

2>深拷贝

1)OC中的字符串是在堆区或常量区存储的对象

2)这个对象由一个栈区的指针指向

3)把这个字符串对象本身复制一份,此时如果有一个指针接受新创建出来的对象的地址,

有两个指针分别指向内容相同但是地址不同的两个字符串对象,这个过程叫做深拷贝

2.copy方法和mutablecopy方法

1>格式

- (id)copy;

- (id)mutableCopy;

2>来源

是NSObject中的方法,任何NSObject子类都拥有者两个方法.

3>有什么用

"copy和mutableCopy两个方法和可变对象或不可变对象结合在一起使用,可以实现深拷贝或浅拷贝

新对象  = [可变对象/不可变对象  copy/mutableCopy]

不可变对象 --- copy --- 浅拷贝

不可变对象 --- mutablecopy --- 深拷贝 -- 结果是可变的

可变对象  --- copy  -- 深拷贝 --- 结果是不可变的

可变对象  --- mutableCopy -- 深拷贝 ---可变的

验证:

可变对象  --- copy  -- 深拷贝 --- 结果是不可变的

int main(int argc, const char * argv[]) {

NSMutableString *Mstr = [NSMutableString stringWithFormat:@"无色大师"];

NSString *MstrCopy = [Mstr copy];

NSLog(@"%p------%p",Mstr,MstrCopy);//不一样说明是深拷贝

NSLog(@"%@------%@",Mstr,MstrCopy);//肯定是一样的

return 0;

}

//下面代码验证结果是不可变对象

int main(int argc, const char * argv[]) {

NSMutableString *Mstr = [NSMutableString stringWithFormat:@"无色大师"];

NSMutableString *MstrCopy = [Mstr copy];

NSLog(@"%p------%p",Mstr,MstrCopy);

NSLog(@"%@------%@",Mstr,MstrCopy);

[MstrCopy appendString:@"123"];//运行崩溃

return 0;

}

#program mark - 25 @property参数copy [重点掌握]

"需求

1.在IOS开发过程中,tableView是一种常用的表格视图.其中每一行叫做一个cell

2.定义一个cell类,这个cell类有一个NSString类型的标题属性.

3.在main.m中模拟请求网络数据3次网络数据,每次请求结束会获得一个字符串标题,此时就创建一个cell对象并将标题赋值给这个cell对象的标题属性,要求每次解析都用同一个可变字符串接收标题.

用NSLog模拟网络请求数据.

"随堂代码/25 @property参数copy/1_copy参数

int main(int argc, const char * argv[]) {

//1.定义一个可变字符串存储请求到标题的字符串

NSMutableString *titleStr = [NSMutableString string];

//2.第一次网络请求

NSLog(@"请求第一个标题---北京某男子地铁中跳舞");

//获取标题

[titleStr setString:@"北京某男子地铁中跳舞"];

//创建cell对象

MKCell *cell1 = [[MKCell alloc] init];

//给cell对象设置标题

cell1.title = titleStr;

NSLog(@"%@",cell1.title);

//3.第二次网络请求

NSLog(@"请求第一个标题---北京某男子地铁中洗头");

[titleStr setString:@"北京某男子地铁中洗头"];

MKCell *cell2 = [[MKCell alloc] init];

cell2.title = titleStr;

NSLog(@"%@",cell2.title);

//4.第三次网络请求

NSLog(@"请求第一个标题---北京某男子地铁中玩手机");

[titleStr setString:@"北京某男子地铁中玩手机"];

MKCell *cell3 = [[MKCell alloc] init];

cell3.title = titleStr;

NSLog(@"%@",cell3.title);

//问题

//NSLog(@"----%@",cell1.title);

return 0;

}

"解决

把cell类中属性strong改为copy

原理

可变对象----copy---深拷贝----结果是不可变对象

"结论

对象的NSString/NSMutableString属性,统一用copy修饰.

@property(nonatomic,copy)NSString * title;

#program mark - 26 单例设计模式 [重点掌握]

1.单例设计模式

单例:单个对象

1个类的对象无论在合适创建,无论创建多少次,创建出来的对象都是同一个对象

2.

1>.创建对象的方法

+alloc方法 这个方法在内存中申请空间创建对象

这个方法只是调用了另一个 +allocWithZone;

重写此方法

+(instancetype)allocWithZone:(struct _NSZone *)zone{

static id instance = nil;

if (instance == nil) {

instance = [super allocWithZone:zone];

}

return instance;

}