Ojbect C中内存管理漫谈.

      

     在java中内存管理机制最基本最原始的是引用计数的方式来管理内存,堆内存中一个对象的引用为空时,那么这个对象在虚拟机垃圾回收时最容易被回收掉。java中的引用是有向线段来表示。当有循环引用的时候我们采用弱引用的方式来相互引用,这样系统会根据自己的需要来回收掉其中的对象内存。其实Object C的内存和这个基本类似。             

             在object-c中,系统自动会为每个创建的对象保存一个引用计数器。当对象被创建时,引用计数设置为1,每一次必须保持该对象时,需要发送(即调用)retain来使得引用计数加1。不再需要对象时,可以发送release消息,使得引用计数减1。当引用计数为0的时候,系统就会释放它的内存(通过向对象发送dealloc消息,也就是真正地去回收对象的内存)。另外,可以用retainCount来得到这个对象的引用计数,返回的类型是NSUInteger整数。基本的调用方式如下:

[obj retain];

[obj release];

[obj retainCount]; 

1、下面通过一个例子来理解retain,release以及retainCount,从而来理解Object C的内存

//1. ClassTest1.h
#import <Foundation/NSObject.h>
@interface ClassTest1: NSObject 


@end

//2. ClassTest1.m
#import "ClassTest1.h"
@implementation ClassTest1
//在.h中有声明,不必声明dealloc方法
-(void) dealloc {
    printf( "Deallocing ClassTest1\n" );
    [super dealloc];
}
@end

//3. main.m
#import <stdio.h>
#import "ClassTest1.h"


int main( int argc, const char *argv[] ) {
    printf("test case 1:\n");
    ClassTest1 *obj1 = [[ClassTest1 alloc] init];
    ClassTest1 *obj2 = [[ClassTest1 alloc] init];


    printf( "obj1 retain count: %i\n", [obj1 retainCount] );
    printf( "obj2 retain count: %i\n", [obj2 retainCount] );


    printf("test case 2:\n");
    [obj1 retain]; // 2
    [obj1 retain]; // 3
    [obj2 retain]; // 2


    printf( "obj1 retain count: %i\n", [obj1 retainCount] );
    printf( "obj2 retain count: %i\n", [obj2 retainCount] );
    
    printf("test case 3:\n");
    [obj1 release]; // 2
    [obj2 release]; // 1


    printf( "obj1 retain count: %i\n", [obj1 retainCount] );
    printf( "obj2 retain count: %i\n", [obj2 retainCount] );
    
    // release
    [obj1 release]; // 1  //这里要注意,有几个retain,就要有几个release.
    [obj1 release]; // 0  //而且,只调用一次delloc
    [obj2 release]; // 0


    return 0;
}
执行后的结果:

test case 1:
obj1 retain count: 1
obj2 retain count: 1
test case 2:
obj1 retain count: 3
obj2 retain count: 2
test case 3:
obj1 retain count: 2
obj2 retain count: 1
Deallocing ClassTest1
Deallocing ClassTest1

说明:

  (1).retain了多少次,就要release多少次, 而且delloc方法只会被调用一次; 
  (2). 一个原则是,是你自己申请的内存,就得由你来负责释放它;而不是你申请的,请不要随意去释放它,这不是你的责任; 
  (3). 每次retain对象时,应该release或autoreleas它。 
在老版本的IOS中对象的retainCount必须为0的时候这个对象才能被释放掉。

2、强引用和弱引用

     默认情况下,一个指针都会使用 __strong 属性,表明这是一个强引用。这意味着,只要引用存在,对象就不能被销毁。这是一种所期望的行为:当所有(强)引用都去除时,对象才能被收集和释放。不过, 有时我们却希望禁用这种行为:一些集合类不应该增加其元素的引用,因为这会引起对象无法释放。在这种情况下,我们需要使用弱引用(不用担心,内置的集合类 就是这么干的),使用 __weak 关键字。NSHashTable 就是一个例子。当被引用的对象消失时,弱引用会自动设置为 nil。
1.(weak与strong)不同的是:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使改对象还有_weak类型的指针指向它;
2.一旦最后一个指向该对象的strong类型的指针离开,这个对象将被释放,如果这个时候还有weak指针指向该对象,则会清除掉所有剩余的weak指针
       所以当我们有循环引用的时候,这时候用弱引用会避免内存泄漏


3. 自动回收原理简介

要使用自动回收我们必须手工创建自动释放对象池,NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。当NSAutoreleasePool自身释放的时候,会遍历数组中的所有对象,并且调用release方法。如果对象的retainCount=0 那么系统会释放这些对象,如果retainCount>0,则会内存泄露。
在某些情况下,NSAutoreleasePool 调用的销毁方法比较迟,这个时候会占用大量的内存,我们也可以使用内嵌的方式,创建多个NSAutorelease的实例,让占用的资源立马释放掉。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在将数据存储到浏览器本地缓存时,需要将数据序列化为字符串格式,因为浏览器本地缓存只能存储字符串。 JSON是一种常用的字符串格式,可以很方便地将JavaScript对象序列化为JSON字符串,并且在需要时可以将其反序列化回JavaScript对象。 因此,存储到浏览器本地缓存的数据应该是JSON字符串格式的数据,而不是JavaScript对象。如果你想存储一个JavaScript对象,需要将其转换为JSON字符串,可以使用JSON.stringify()方法。在读取数据时,需要使用JSON.parse()方法将JSON字符串转换回JavaScript对象。 ### 回答2: 存储到浏览器本地缓存通常使用的是键值对的形式,而本地缓存的值只能是字符串类型。因此,无论是存储到浏览器本地缓存还是从浏览器本地缓存读取数据,都需要将数据转换为字符串。 JSON(JavaScript Object Notation)是一种常用的数据交换格式,它可以将Javascript对象转换为字符串的形式,并可以方便地进行解析和序列化。因此,当我们将数据存储到浏览器本地缓存时,可以将数据转换为JSON字符串,以便于存储和读取。 而对象(Object)类型是Javascript的基本数据类型之一,它是由一组键值对组成的无序集合。虽然对象也可以通过一些方法(例如JSON.stringify())转换为字符串,但在存储到浏览器本地缓存时,需要将这个字符串再转换回对象才能使用,这样增加了操作的复杂性。 因此,为了简化数据存储和读取的操作,并提高代码的可读性和可维护性,我们一般建议在存储到浏览器本地缓存时使用JSON格式来进行数据转换和存储。这样可以方便地通过JSON.stringify()方法将对象转换为JSON字符串存储,而在读取数据时,可以使用JSON.parse()方法将JSON字符串转换回对象。这样可以更加方便地操作和获取存储在浏览器本地缓存的数据。 ### 回答3: 存储到浏览器本地缓存可以使用JSON格式,因为JSON是一种轻量级的数据交换格式,易于读写和解析。在前端开发,常常使用JSON来表示和传输数据。 使用JSON格式存储到浏览器本地缓存的好处是可以将Javascript对象转换为JSON字符串进行存储,而在需要读取时,可以将JSON字符串转换回Javascript对象。这样可以很方便地将复杂对象转换为可存储的文本,并在需要时进行恢复。JSON格式还可以按照属性键值对的方式存储数据,使数据结构清晰可读,方便在后续操作进行解析和处理。 相比之下,将Javascript对象直接存储到浏览器本地缓存是不可行的。因为浏览器本地缓存通常只能存储字符串形式的数据,无法存储Javascript对象。如果尝试直接存储Javascript对象,会抛出错误或存储失败。 因此,为了在浏览器本地缓存正确地存储和读取数据,我们应该将数据转换为JSON字符串进行存储,或者在读取时将JSON字符串转换回Javascript对象。这样可以保证数据的可靠存储和高效读取。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值