生命周期
每当对象创建出来,它的生命就已经开始了,一直到操作系统释放了 该对象,对象的生命才结束
基于计数器的内存管理
每个对象都有 一个引用计数器,它记录了对象被使用的情况。
当使用 alloc、copy、new 三种方法之中的任一种方法创建对象时,对象计数器会被自动设 置为 1。
如果向对象发送 retain 消息,对象计数器会自动加 1。而向对象发送 release 消 息,对象计数器会自动减 1。
如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。
原理
当调用对象autorealse方法后,对象的引用计数没有减一,对象就进入了autorealsepool当中,当autoreleasepool被pop时,会对池中的所有对象进行release一次,从而进行对象释放。
@autoreleasepool
自动释放池可以延长对象的声明周期,如果一个事件周期很长,比如有一个很长的循环逻辑,那么一个临时变量可能很长时间都不会被释放,一直在内存中保留,那么内存的峰值就会一直增加,但是其实这个临时变量是我们不再需要的。这个时候就通过@autoreleasepool创建新的自动释放池来缩短临时变量的生命周期来降低内存的峰值。
过程
属性修饰符用来指示数据可访问性与特性,共有一下几个关键字
@property (copy, nonatomic) NSString *var;
------------------等效分割线------------------
@synthesize var;
- (NSString *)var {
@synchronized(self) {
return _var;
}
}
- (void)setVar:(NSString *)var {
@synchronized(self){
_var = var;
}
}
@property (nonatomic, strong) NSString *str;
NSString *first = @"Hello";
self.str = first;
first = nil;
代码解释,first是强指针引用,之后str也指向”Hello”这个内存,
当str是Strong类型时,虽然first这个指针没有了,但是有str强引用,@”hello”依然不会被释放。
当str是weak类型时,first指针被清空,只有str弱引用,@”hello”会被释放
weak指针置为nil?
{
id __weak obj_weak = obj;//obj已被赋值。而且是strong类型的
}
Runtime维护了一个Weak表,用于存储指向某个对象的所有Weak指针。Weak表其实是一个哈希表,objc_storeWeak函数以把obj的地址作为键值,obj_weak的地址作为值存放到weak表(weak是一个hash表)中。
当obj对象引用计数为0时,就要delloc被回收,objc_clear_deallocating方法将obj_weak置为nil,并且将记录从weak表中清楚
保证局部变量永远只初始化一次,在程序的运行过程中永远只有一份内存
先看一下区别
for (int i = 0; i < 10; i ++) {
int a = 0;
a ++; //打印结果
NSLog(@"a=%d",a);
}
//打印结果是:
a = 1
a = 1
a = 1
...
加Static关键字
for (int i = 0; i < 10; i ++) {
int static a = 0;
a ++; //打印结果
NSLog(@"a=%d",a);
}
//打印结果是:
a = 1
a = 2
a = 3
...
使全局变量的作用域仅限于当前文件内部,即当前文件内部才能访问该全局变量。
+ (SingleObject *)sharedSingleton{
static SingleObject *_singleObj = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_singleObj = [[self alloc] init];
});
return _singleObj;
}
(1 const用来修饰右边的基本变量或指针变量 (2 被修饰的变量只读,不能被修改
int const *p // *p只读 ;p变量
int * const p // *p变量 ; p只读
const int * const p //p和*p都只读
int const * const p //p和*p都只读
我们可以在.h文件中extern声明一些全局的常量
.h声明一些全局常量
extern NSString * const name;extern NSInteger const count;
然后在.m文件中去实现
.m实现
NSString *const name = @"helloted";
NSInteger const count = 6;
这样,只要导入头文件,就可以全局的使用定义的变量或常量。