智能指针的原理及实现

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

智能指针(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. Java List集合和哈希表

    List集合和Set集合,先来看List集合. List集合存储元素的特点: 1.有序(List集合中的元素有下标):存进去是什么样,取出来还是什么样 2.可重复 可以结合以下的简单代码来看一看. i ...

  2. C Primer Plus note1

    C语言编译错误:multiple definition of `main' main多重定义,在同一个工程中定义了多个main函数 出现如下图的错误: 这是因为在第一张图中,有一个main.c的mai ...

  3. php explode时间分割

    <?php $str = "2017-02-27 13:40:42"; $first=explode(' ',$str); $second=explode('-', $fir ...

  4. IO流之 commons-IO

    commons-IO 导入classpath 加入classpath的第三方jar包内的class文件才能在项目中使用 创建lib文件夹 将commons-io.jar拷贝到lib文件夹 右键点击co ...

  5. Can't read stdin: end of file found

    问题是在我修改svn的账号和密码后出现的,因为百度出来的情况只有一种答案,所以记录一下我的情况,给其他人多一种排查思路.问题根源是,由于该版本库只有一个账号,更改了账号密码,没有同步修改post-co ...

  6. 移动端Hybird的网络层优化策略

    一.前端代码策略:域名切换(多域名部署),解决DNS缓存及域名劫持 二.客户端策略 客户端在空闲时ping cdn节点域名列表中的域名,测量延时.丢包等数据.如果延迟 > xxx,丢包 > ...

  7. ajax方法XHR.readyState五种状态与示例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. URL传递中文:Server.UrlEncode与Server.UrlDecode

    1.设置web.config文件. <system.web>  ......  <globalization requestEncoding="gb2312" r ...

  9. 查看postgre都有哪些语句占用CPU

    查看占用CPU最多的几个postgresql ps aux | grep postgres | sort -n -r -k 3 | head -10 | awk '{print $2, $3}' 查看 ...

  10. 《Visual C++ 2010入门教程》系列五:合理组织项目、使用外部工具让工作更有效

    原文:http://www.cnblogs.com/Mrt-02/archive/2011/07/24/2115631.html 这一章跟大家分享一些与c++项目管理.VAX.SVN.VS快捷键等方面 ...