iOS 释放内存/指针清空(release/=nil)深度讨论

Objective-C内存管理

(1)release/=nil,前后顺序是可以随便用。并且=nil是可以用无数次。

<wbr><wbr><wbr><wbr><wbr><wbr>事实: Object *object=[[Object alloc] init];</wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>object=nil;</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>object=nil;</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>object=nil;</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>……</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>object=nil;//都不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr>事实: Object *object=[[Object alloc] init];</wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>object=nil;</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>[object release];//也不会报错。*指针一定要为空,release才可以用无数次。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

(2)两个指针指向同一个对象,其中一个指针清空(=nil),不影响另一个。如下两个图,比较可知:


(3)两个指针指向同一个对象,其中一个释放内存【即retainCount - 1】(release),影响另一个。如果引用到另一个指针的话会报错:


如果你开了:NSZombieEnabled,引用被释放的对象时,报错如下:*** -[objcect respondsToSelector:] message sent to deallocated instance 0x6a109f0

<wbr>(注意:containObject.delegate 的setter方法是assign)</wbr>

**************************************************************************************************

对比一:

①调用[objcet release]后,指针仍然指向内存块:0x6a109f0

②而调用object=nil(containObject.delegate=nil)后,指针不指向任何内存块,即内存地址:0x0
**************************************************************************************************

对比二:

①引用一个retainCount=0的指针,是出错的:

<wbr>[object release];</wbr>

<wbr>NSLog(@"%@",object);//出错<br> ②引用一个内存地址:0x0的指针,是不会出错的:</wbr>

<wbr>object=nil;</wbr>

<wbr>NSLog(@"%@",object);//不出错</wbr>

*************************************************************************************************

嘘……下面我来一个高度的概括,连苹果官网都没我这个概括那么概括。千万不要告诉人家(不过你告诉人家,我也没办法,不绝对不会追究知识产权的)。

一个指针调用 release 函数,是会影响到所有指向同一对象的指针。总的来说,释放内存(rlease)方面,所有的指针是Shared的。

一个指针=nil,只会影响到本身,不会影响到所有指向同一对象的其它指针。总的来说,指针清空(=nil)方面,所有的指针是Independent的。


采用除留余数法定义哈希表,哈希表长度为 20,哈希函数为H(key)=key。产生冲突时采用线性探测法实现哈希表的建立、插入、查找、删除等功能。#include<stdio.h> #define NIL 0 /* 用NIL作为空闲单元的标志 */ #define DelNIL -1 /* 用DelNIL作为已删除单元的标志 */ #define m 13 #define n 20 typedef struct { int key; } LHashTable; /* 初始化哈希表 */ void HashListInit(LHashTable HT[n]) { int i; for (i = 0; i < n; i++) HT[i].key = NIL; } /* 清空哈希表 */ void HashListClear(LHashTable HT[]) { int i; for (i = 0; i < n; i++) HT[i].key = NIL; } /* 定义哈希函数 */ int Hash(int k) { return (k % m); } /* 在哈希表中查找元素 */ int HashListSearch(LHashTable HT[n], int k) { int d, temp; d = Hash(k); /* 计算k的哈希地址 */ temp = d; /* temp暂存k的哈希地址 */ while (HT[d].key != NIL) { //TODO 在哈希表中查找到元素k //=======begin====== //========end======= else /* TODO 没找到进行线性探测法继续查找 */ //=======begin====== //========end======= if (d == temp) return -1; /* 哈希中没有待查元素k */ } return -1; } /* 在哈希表中插入一个元素 */ void HashListInsert(LHashTable HT[n], int k) { int d, temp; d = Hash(k); /* 计算k的哈希地址 */ temp = d; /* temp暂存k的哈希地址 */ while (HT[d].key != NIL && HT[d].key != DelNIL) /* 当前位置已有元素 */ { /* TODO 进行线性探测 */ //=======begin====== //========end======= if (d == temp) { printf("哈希表无空间\n"); /* 哈希表已满 */ //exit(1); } } /* TODO 插入k */ //=======begin====== //========end======= } /* 从哈希表中删除元素 */ void HashListDelete(LHashTable HT[n], int k) { int d, temp; d = Hash(k); temp = d; while (HT[d].key != NIL) { if (HT[d].key == k) { /* TODO 找到k,写上删除标志 */ //=======begin====== //========end======= return; } else /* TODO 当前位置没找到k,进行线性探测 */ //=======begin====== //========end======= if (d == temp) break; } printf("哈希表中无待删除元素%d\n",k); //exit(1); } /* 输出哈希表中所有元素 */ void PrintHashList(LHashTable HT[n]) { int i; for (i = 0; i < n; i++) printf("%d ",i); printf("\n"); for (i = 0; i < n; i++) printf("%d ",HT[i].key); } int main() { //主函数信息请勿修改 int k; LHashTable HT[n]; HashListInit(HT); printf("请输入要插入到哈希表中的关键字,以0结束:\n"); scanf("%d",&k); while (k != 0) { HashListInsert(HT, k); scanf("%d",&k); } printf("所建立的哈希表长为20,哈希函数为H(key)=key%13\n"); PrintHashList(HT); printf("\n请输入要查找的关键字:\n"); scanf("%d",&k); k = HashListSearch(HT, k); if (k == -1) printf("哈希表中无此元素\n"); else printf("查找的关键字位置为:%d\n",k); printf("请输入要删除的关键字:\n"); scanf("%d",&k); HashListDelete(HT, k); printf("删除成功后的哈希表为:\n"); PrintHashList(HT); }
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值