FoundationDAY01
来源:互联网 发布:淘宝卖鲜花资质 编辑:程序博客网 时间:2024/06/11 23:26
day 07内存管理
一、知识点回顾
1.为什么要进行内存管理?
因为移动设备的内存空间是有限的。所以每一个应用程序或游戏所占的内存也是有限的。
当应用程序使用内存过多时,系统就会发出低内存警告,这时候就需要我们回收一些内存资源。
简单的说就是回收了一些现在不使用的对象或者变量。
2.对象的创建和销毁
1.第一种创建对象的方式 NSObject类
+(id)alloc方法是+方法 和-(id)init方法是-方法 套写创建对象,OC中较为常见的一种。
2.第二种创建对象的方式 C++ Java风格的创建对象.
+(id)new方法
Student *stu1 = [Student new];
3.对象的销毁
当对象的引用计数为0时 系统自动调用了
-(void)dealloc 方法来释放对象
{
[super dealloc]; //MRC有 且写在最后。
}
3.对象的基本结构
每一个OC中对象都有一个引用计数器,是一个用整数表示对象被引用的次数。
简单的说就是当前有多少个指针指向这个对象。
对象创建时计数器的值为1.当计数器的值为0时 对象被销毁。
核心原理:
1.对象所有权的概念——>体现——>引用计数
4.引用计数器的作用
判断对象要不要回收内存的一个依据。
系统会自动判断对象的引用计数器——>值——>是不是0,如果是0值就要自动调用-(void)dealloc 析构函数
引用计数
每一个OC的对象都有自己的引用计数器,是用一个整数表示对象的被引用的次数。每个对象的内部,都有专门的 4个字节的存储空间来保存引用计数的值。
5.引用计数器的操作
1.MRC 手动引用计数的操作
1.retain 方法 作用使得引用计数器+1
2.release 方法 作用使得引用计数器- 1
(并不是销毁对象 也不是释放内存) 3.retainCount方法 获得当前对象的引用计数的值。
4.自动释放池 @autoreleasepool{
}
autoreleasepool 方法 作用是自动释放池中使用的一种消息,他不会立即造成对象的应用计数的- 1.
是延时释放的。当自动释放池被销毁是,才能向释放池中的每一个对象发送消息,来销毁对象。
注意:当不能确定这个对象何时被销毁时,我们通常使用autorelease但是要神勇。效率低。
内存管理的原则:
1.谁创建 谁释放的原则
谁 alloc new 谁 release
2.谁retain 谁release
3.责任制原则
1>对象该释放时 没有释放。(程序员的疏忽大意)。
2>不该释放时 对象提前释放了。(程序会崩溃或无响应)。
2.ARC 自动引用计数的操作
你只需要创建对象即可 对象的retain操作 release操作 autorelease操作 都不能继续使用,系统自动完成
引用计数判断对象是否需要释放或自动持有。
注意:在重写 -(void)dealoc方法时 ARC中 不能写[super dealloc];//不让你调用
retatinCount
6.内存管理中代码规范
1.只要调用了alloc方法或new方法 就必须有release或autorelease。
2.重写set方法的代码规范
1>如果是基本数据类型 NSUInteger NSInteger 等
直接赋值
-(void)setAge:(NSUInteger)age
{
_age = age;//直接赋值表达式赋值
}
2>如果是OC对象 的set方法的重写
-(void)setStudent:(Student *)student
{
if(_student! = student)
{
//先把原来的旧的对象 释放
[_student release];
//对新对象 进行一次retain操作
_student = [student retain];
}
}
3>-(void)dealloc 方法的代码规范
1>一定要有dealloc方法,[super dealloc]且要放在最后。
2>如果声明了成员变量
Student *_student;
-(void)dealloc
{
[_student release];
[super dealloc];
}
7.属性北村管理 @property(内存管理)属性类型 属性名
1.属性内存管理的相关参数
assign:作用 是直接赋值(凡是非OC对象 默认)
比如:int char double long bool NSUInteger等
特别注意的:
MRC中使用协议委托时
@interface 委托类:NSObject
@property(nonatomic,assign)id<xxxxxx>delegate;
@end
协议委托中委托人的属性为什么用assign?
1.防止循环引用。
为什么用id类型?
2.id表示泛型<协议>表示类具有通用性。
协议的作用?
3.就是分散接口的作用。
retain的作用:释放旧值 ,retain新值(适用于OC对象)
一般用于自定义类 Student *; Car *;retain的是指针 不是复制对象。
copy:作用 释放旧值,复制新值。copy的对象。
1>凡是字符串类型都用copy NSString类型 NSMutable String
2>见到Block 做属性时 用copy
遵守<NSCoping>协议的对象
总结:retain 的是指针 copy 的是对象;
2.属性的参数第二类 修饰set方法的
readonly:只读就表示 这个属性只是自动生成get方法
@property(readOnly)NSUInteger age;//只有get 没有set
readwrite:系统默认 同时生成set 和 get 方法;
3.多线程的管理(线程安全问题)
nonatomic: 高性能,关闭了多线程,保护变量,一般默认为该选项。
atomic:低性能 很少使用 系统中默认开启atomic多线程。
8.内存管理中的循环引用问题以及解决方式
例子:
每个人都有一部手机,每一个手机又对应一个人。写程序时 不能两个类之间的头文件互相包含。#import “a.h
” #import “b.h” 这就是循环引用。
关键字 @class:声明的是一个类,告诉给编译器 某一个标示符@class标示符 是一个类。
实际开发中:
在导入一个类时 都建议使用
xxx.h 中包含一个类
@class ClassA;
@class ClassB;
xxx.m文件中使用某一个类中得内容
#import<ClassA>
2.两端循环引用的解决方式(真出现循环引用的时候)
一端使用retain 另一端使用assign
注意:使用assign端 -(void)dealloc 不用再release
ARC
1.ARC的判断准则
只要没有强类型的指针指向对象 对象就会被释放。
2.指针的分类
1.强类型的指针:strong 默认情况下所有的指针类型都是强类型。
2.弱类型的指针:weak。
看demo
二、Block 块语法($3000)
1.Block封装了一个段代码,可以在任何时候执行。
2.Black可以作为函数参数或函数的返回值。
3.Block回调。
4.Block用于多线程、异步任务、集合类的便利、集合类排序动画的转场。
5.Block访问全局变量和局部变量。
6.Block反向传值。
2.Block块的声明
Block是苹果公司推荐使用的一种数据类型。
特点:1.效率高 在运行中保存代码。常用来封装和保存代码,一般底层函数较多。有点像函数,Block可以在
任何时候执行。
和函数的相似性:
1.都可以用来保存代码
2.都可以由返回值
3.都可以由参数
4.调用的方式相同
C语言中的函数指针
void(*p)(int );
void(^p)(int);
3.Block的标示符 ^
3.1Block块的声明
返回值类型 (^变量名)(参数类型);
3.2Block块的声明和实现写在一起
void(^myBlock)(int) = ^(int n)
{
//块的内容
for(;;)
{
NSLog(@"Hello World");
}
};
3.3Block块 的调用
myBlock(10);//打印十次hello world。
四、NSNumber 数字对象
提供的是一个OC中得Foundation 框架中的类,作用就是把C语言中得基本数据类型 int char float double long bool等这些数值数据封装成一个NSNumber 数字对象的类。
NSNumber 是 NSValue的一个子类。
作用:数字变量——>数字对象——>在OC中使用了
- (id)initWithChar:(char)value;
- (id)initWithUnsignedChar:(unsigned char)value;
- (id)initWithShort:(short)value;
- (id)initWithUnsignedShort:(unsigned short)value;
- (id)initWithInt:(int)value;
- (id)initWithUnsignedInt:(unsigned int)value;
- (id)initWithLong:(long)value;
- (id)initWithUnsignedLong:(unsigned long)value;
- (id)initWithLongLong:(long long)value;
- (id)initWithUnsignedLongLong:(unsigned long long)value;
- (id)initWithFloat:(float)value;
- (id)initWithDouble:(double)value;
- (id)initWithBool:(BOOL)value;
- (id)initWithInteger:(NSInteger)value NS_AVAILABLE(10_5, 2_0);
- (id)initWithUnsignedInteger:(NSUInteger)value NS_AVAILABLE(10_5, 2_0);
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value NS_AVAILABLE(10_5, 2_0);
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value NS_AVAILABLE(10_5, 2_0);
- FoundationDAY01
- 现代汽车电子设备控制
- Redis的字典(dict)rehash过程源码解析
- os X的文件夹名称的本地化显示
- [C++]LeetCode: 30 Minimum Depth of Binary Tree
- VC只运行一个实例运行,创建互斥体
- FoundationDAY01
- Android 实现个性的ViewPager切换动画 实战PageTransformer(兼容Android3.0以下)
- Android数据库随同Android应用一同发布
- MFC 学习之 界面美化<1>
- 简单数据持久化/NSUserDefaults(单例) 登陆界面简单验证
- App界面设计:发现闪屏之美
- 1212
- C++名称查找与ADL
- poj 3190 Stall Reservations1