如果我们使用 creat new copy 等函数,就会开辟一段堆空间,返回一个对象。
用一个指针指向这个对象:ptr = obj;
,我们要释放这块对象的内存,就可以这样做:free(ptr);
,这时在堆上的内存就已经被释放了。但这还没有完,虽然我们堆上的空间已经被释放了,但是ptr
里面还是有值的,如果仍然在程序中使用ptr
指针的话就会出现坏内存访问的问题。正确的做法是在free
之后,再清空指针:ptr = NULL;
。
如果上述步骤先执行的是ptr = NULL
,那么堆上的这块内存将永远不会被释放!
在 OC 中创建的 CF 对象,内存是不被 ARC 所管理的。假设有一个 CF 对象 cfObj 和指针 cfPtr: cfPtr = cfObj;
。
当 cfObj 创建的时候会占用堆上的一块内存,记为堆空间1
。
cfObj 本质上是一个结构体,它里面可能有其它的指针,它们都有可能会创建新的堆空间记为堆空间2~N
。
如果调用 free(cfPtr),那么仅仅只会释放堆空间1的内存,堆空间2~N将永远不会被释放。
如果使用 CFRelease(cfPtr),它会先释放堆空间2~N,再释放堆空间1。它们都会得到释放。
还有一个问题
上面提到了使用 free 之后要将指针置为 NULL 才能将指针清空。
那么使用 CFRelease 之后,要不要置为 NULL?
我在测试的时候发现,如果只是 CFRelease(cfPtr) 的话,释放之后 cfPtr 里面存储的还是之前的地址,如果在执行 cfPtr = NULL 的话,cfPtr 的值才会变成 0x0000000000000000
。也就是说 CFRelease 也需要置 NULL 才能清空指针。
那为什么平时看别人写的代码中似乎没有这样的操作?我觉得是当程序执行完函数后 cfPtr 在栈上的空间会被销毁,一般不会造成问题。
以上是个人的看法,如果有误的话请指出来!