智能指针的原理及实现

当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。
智能指针:
当类中有指针成员,创建几个对象,
当有几个对象 共同用一个资源时,则它们同时指向了这个资源,如果用普通的指针,则在其中一个对象析构时就会将这个共用的资源销毁,有了智能指针就不用担心,它里面有对象计数,代表有几个对象在用它,销毁一个就减1,直到为0,为0时就表示没有对象用这个资源了,就会自动释放资源存储区!还有很多智能的地方
@interface Quotation:NSObject
{
NSString *id;
        NSString *name;
NSString *price;
Account *account;
}
在oc的对象中,成员都是指针,对于id,name,price属性,类对象维护各自那份内存,但是对于account属性,很多情况下,很多quotation对象会共享一份account,这种情况下就需要使用智能指针了。
比如
{
Quotation *quotation1 =[ [Quotation alloc] init];
quotation1.name = @"gold";
quotation1.price = @"12.7";
Quotation *quotation2 =[ [Quotation alloc] init];
quotation2.name = @"dollor";
quotation2.price = @"12.2";
}
quotation1与quotation2的price指针并不共享一块内存,各自维护自己的内存。

如果是下面的情况,使用智能指针就比较好:

{
Account *currAccount = self.account;
Quotation *quotation1 =[ [Quotation alloc] init];
quotation1.account = account;
Quotation *quotation2 =[ [Quotation alloc] init];
quotation2.account = currAccount; 
[currAccount release];
//上面的情况,如果quotation类的account属性不是retain的,而是普通的assign赋值:
quotation1,quotation2的account指向了同一块内存,如果quotation1把account内存释放了,那么quotation2的account就是个野指针了,因为account指向的内存已经被quotation1释放了。这种情况下,quotation2使用account就crash了。这种情况下就需要用智能指针来防止。
当果quotation类的account属性是retain的:
[currAccount release];//虽然currAccount被release了,但是currAccount被quotation1对象保留了一次,所以currAccount并没有被释放,当quotation1对象释放currAccount的时候,他也不一定被释放,因为quotation2又保留了它,所以只有当currAccount的引用计数器为0的时候他才会被释放,在oc中,通过设置retain属性就是智能指针的应用。quotation1与quotation2对象共享了一块内存currAccount。通过引用计数器解决共享内存释放的问题。
}
由此可见,oc中的指针只要是retain属性就默是智能指针,通过引用计数器来实现指针指向的对象的共享。最终控制指针指向的内存的释放。
在oc中基本上所有的对象都是retain(或者strong)属性,除了delegate对象(为了防止循环引用)。
在oc中,对象如果不用retain智能指针,而是使用普通的指针,那么就会出现某个对象释放了共享内存,另一个对象再使用这块内存的时候crash的问题。
oc的内存管理使用引用计数器,也就是使用智能指针管理。智能指针的作用就是来管理共享内存的释放,只有当retainCount为0才能释放共享内存。

智能指针 与 oc中的指针的更多相关文章

  1. OC中的指针

    NSError *err = nil; NSError __strong **error = &err; //因为在oc中,通过* *err 创建的指针是用__strong修改的,所以要一致, ...

  2. 新手学习之浅析一下c/c++中的指针

    一.我们先来回忆一下指针的概念吧,方便下面的介绍 指针是存放地址值的变量或者常量.例如:int a=1;&a就表示指针常量(“&”表示取地址运算符,也即引用).int *b,b表示的是 ...

  3. c语言中,指针加1的情况.指针变量详细介绍

    指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 要搞清一个指针需要搞清指针的四方面的内容: 指针的类型, 指针所指向的 类型, 指针的值或者叫指针所指向的内存区, 还有指针本身所占 ...

  4. [BS-21] 关于OC中对象与指针的思考

    关于OC中对象与指针的思考 1. 创建对象: OC中可通过代码Person *p = [[Person alloc] init];创建了一个对象p.该过程中内存情况为: 在当前线程的栈(默认1M)中, ...

  5. OC中的self指针

    在OC中,self是一个指针,方法和属性可以通过self.function进行访问:成员变量使用self->变量名进行访问.调用方法还可以用[self function]; OC中的self有点 ...

  6. OC中的野指针(僵尸指针)

    涉及到内存管理问题的都是类类型的变量,而在OC中我们操纵这些对象都是通过操纵指向他们的指针来完成的,一致很多时候会忽略指针存在.比如定义UIView * view = [[UIView alloc]i ...

  7. OC中的野指针,空指针,nil,Nil,NULL,NSNULL小结

    周末与一个老朋友吃饭聊天,因为他正在培训班学习iOS开发,就随便聊了几句,发现自己OC基础上的欠缺和一些知识点的混淆.特此整理如下. 1.空指针 没有存储任何内存地址的指针就称为空指针(NULL指针) ...

  8. 谈谈自己对C语言中函数指针的一些理解 (第一次写博客,有点小兴奋哈)

    1.函数指针声明的格式及简单的使用 (1)格式:(返回值)(*函数指针名)(参数列表)    例如:声明一个无参数无返回值的函数指针(void)(*p)(void). (2)将函数指针指向某个无参数无 ...

  9. GO语言中的指针

    http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...

随机推荐

  1. Golang 的 TOML库

    TOML 的全称是 Tom's Obvious, Minimal Language,因为它的作者是 GitHub 联合创始人 Tom Preston-Werner. TOML 的目标是成为一个极简的配 ...

  2. Excel删除空白行和列

    Sub DeleteEmptyRows() Dim LastRow As Long, r As Long LastRow = ActiveSheet.UsedRange.Rows.Count Last ...

  3. 深入理解javascript原型和闭包_____全部

    http://www.cnblogs.com/wangfupeng1988/p/3977924.html

  4. es6 import笔记

    export输出: // profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export ...

  5. HTML5 localstorage和session操作

    setStorage={ getLocal : function(key){ //获得localStorage里面的值 var storage = window.localStorage; if(st ...

  6. [ZOJ3316]:Game

    题面 vjudge Sol 有一个棋盘,棋盘上有一些棋子,两个人轮流拿棋,第一个人可以随意拿,以后每一个人拿走的棋子与上一个人拿走的棋子的曼哈顿距离不得超过L,无法拿棋的人输,问后手能否胜利 首先距离 ...

  7. Bzoj1492: [NOI2007]货币兑换Cash(不单调的斜率优化)

    题面 传送门 Sol 题目都说了 必然存在一种最优的买卖方案满足: 每次买进操作使用完所有的人民币: 每次卖出操作卖出所有的金券. 设\(f[i]\)表示第\(i\)天可以有的最大钱数 枚举\(j&l ...

  8. CentOS 7运维管理笔记(11)----PHP安装与配置

    PHP的安装同样需要经过环境检查.编译和安装3个步骤. 1.首先用百度搜索 “PHP:Downloads”, 点击第一个网页: 选择5.5.37版本,选择 .tar.gz 格式的文件: 来到镜像列表网 ...

  9. daemontools检测进程,退出拉起

    一.学习的原因: 为了实现在服务异常停止运行后,有一个监控程序能监控到它,并自动重新启动这个服务.以下以tomcat为例子 二.工具supervise Daemontools是一个包含了很多管理Uni ...

  10. Android通过浏览器打开app页面并且传递值

    最近公司有个需求,要求从第三方网页端打开一个网页,然后在网页中点击“下载”,“打开”按钮,在app端进行下载和打开操作.这里记录下方法. 首先,网页和app页面进行交互,其实会很快想到JS交互,但是现 ...