ios 内存管理

Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由程序员释放的,即release

栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就需要将

其定义为成员变量。

init 时 系统分配内存 到堆中, 并有一个起始地址

例子: NSObject * object = [[NSObject alloc]init];
* object 指针 指向了 [[NSObject alloc]init] 函数体 [[NSObject alloc]init]函数体(对象)就放在了堆空间里
OC 方法的本质 == C函数 == 函数调用栈

函数被调用时 (可能)会开辟 一段栈空间
栈空间存的是地址 32位/8=4(个字节) 64/8=8(个字节)

函数被调用完毕 内存就释放了  
- (void)addClick{

}
addClick 结束时内存被释放

MRC内存管理

alloc底层是malloc(),返回的是一个指针,所以alloc 时,在堆空间开辟出一块内存,malloc和free是相对应的
malloc 创建 一个对象 堆空间分配内存 返回一个指针在栈空间里
free(void*)   通过一个指针释放堆内存
如果指针没被释放 如果下边程序用指针访问内存 这样会内存泄漏 会崩溃 但也有不 崩溃的情况
通过free释放这块内存就意味着 系统知道这块内存可以用了 , 系统有可能就放一块数据到上面也有可能不放数据
有可能 用这个指针访问时 会访问到其他数据(垃圾数据) 此时不崩溃
指针释放 *p = NULL ; (free 内存了指针没释放就成了野指针)

dalloc 是在 free之前 被调用 为什么 下面会解释

结构体的内存释放是不一样的  为什么不一样先了解下
C 里的函数! 关键字 create new copy 默认都会开辟堆空间(malloc) 都会调用 malloc 创建后都会返回指针地址

mall会返回一个叫 CFRunLoopObserverRef 的指针

例子:
CFRunLoopObserverRef observer = CFRunLoopObserverCreate(...............);(这个observe指针指向一块内存) 创建时 调用 malloc 这个结构体的释放怎么释放?

  在堆里分配内存 释放时 
用free(observer); 还是 CFRelease(observer);

在堆空间里有可能会再次开辟堆空间!!!!!!
结构体里有很多属性 其中 一个属性就是 一个指针 指针会在堆空间开辟空间 

如果用 free(observer); 里面有指针指向 另一块内存,一旦先用free ,那么属性指向的那块内存 会泄漏 所以 结构体

释放要用  CFRelease(observer)

用一个图表示
ios 内存管理

free(observer)

ios 内存管理
CFRelease 这个函数 就是 把函数体里的指针指向的内存全部释放 后 再 释放自己

 

//什么是 Dalloc

Dalloc是在即将free(*指针)//通过指针释放内存之前,调用的方法,为了释放内存之前释放所有指针和内存做一些可必要操作
为什么要在free释放前调用Dalloc?
dalloc 就是要 CFRelease , 如果 直接 free 把对象释放了 那么对象里的指针就没有了, 指针指向的堆空间就泄漏了
目的就是 free之前 清空 堆里指针指向的堆区域 防止内存泄漏