OC语言——内存管理

1-内存管理

1>内存管理

内存管理对于开发iOS来说,很重要,是精髓。学会了内存管理在开发的时候就可以精确分配存储空间。

管理范围:任何继承了NSObject的对象,都需要管理。基本数据类型不需要(int  char  double float struct enum)


2>引用计数器

每个OC对象都有自己的引用计数器,表示对象被引用的次数

一个新对象,默认计数器就是1,成为0则被销毁。系统会自动向对象发送一条dealloc消息。

给对象发送一条retain消息,对象计数器+1;

给对象发送一条release消息,对象计数器-1;

给对象发送一条retainCount,获取当前计数器情况。

一句话:谁retain,谁release。谁alloc,new,谁release(outorelease).

在对象被销毁时,就会调用dealloc方法。

我们可以重写dealloc方法,达到一些需要:

<span style="font-size:18px;">- (void)dealloc
{
    NSLog(@"对象被回收");
    [super dealloc];
}
</span>

僵尸对象:所占内存已经被回收的对象。

野指针:指向僵尸对象(不可用内存)的指针。为了防止野指针错误,p = nil;而[p release],是给空指针发消息。

空指针:没有任何东西的指针(存储的东西是nil,NULL,0),给空指针发送release消息不回报错。



3.内存管理相关的参数

1>retain: release旧值,retain新值。

2>assign:(set方法)直接赋值(默认),@property(assign) int age(适用于非oc对象类型)

3>copy:release旧值,copy新值。


4.set方法内存管理

基本数据类型不需要管理内存

<span style="font-size:18px;">- (void)setAge:(int)age
{
    _age = age;
}
</span>


如果更换某个对象,使用新对象,应该在更换对象前对旧对象进行一次release.

<span style="font-size:18px;">- (void)setCar:(Car *)car
{
    if(car != _car)// 先判断是不是新传进来的对象
    {
        [_car release];// 对旧对象进行一次销毁
    }
    _age = [age retain];// 对新对象retain
}</span>


dealloc方法的代码规范

1>一定要[super dealloc],而且放到最后。

2>对(self)当前所拥有的其他对象做一次release

- (void)dealloc
{// 当人不在了,对车坐一次release操作
    
    [_car release];
    
    NSLog(@"%d岁的person被回收了", _age);
    
    [super dealloc];
}

4.property。

1.简单写法(针对对象类型):

会自动生成book的set方法。会release旧值,retain新值。

<span style="font-size:18px;">@property (retain) Book *book;
</span>

相当于

- (void)setBook:(Book *)book
{
     if(_book != book)
    {
        [_book release];
        _book = [book retain];
    }
}


2.readonly参数和readwrite参数,它们属于同一类型只可以写一个。

//只生成getter的声明和实现

<span style="font-size:18px;">@property (readonly) int height;
</span>

//同时生成setter和getter的声明和实现

<span style="font-size:18px;">@property(readwrite);</span>

3.多线程管理

@nonatomic:性能高,一般使用这个。

@atomic:默认情况下,性能低。


4.setter和getter方法的名称

setter:决定了setter的名称,后面一定要有个冒号:

getter:决定了getter的名称。一般用在bool类型.


<span style="font-size:18px;">@property (getter = abc,setter = setAbc:) age;
</span>

这种方式一般在bool中使用。

例如:

//返回bool类型的方法名一般以is开头

<span style="font-size:18px;">@property (getter = isRich) BOOL rich;
</span>

在外面就可以这样调用:

<span style="font-size:18px;">Person *p = [[Person alloc] init];
p.rich = YES;
BOOL b  = p.isRich;</span>

5.@class仅告诉编译器,它所代表的是一个类。

开发中使用:在.h文件中用@class来声明类,在.m中用#import来包含类的所有东西。

两端循环的引用办法:一端用retain,一端用assign。


6.autorelease

autorelease方法会返回对象本身,会将对象放到一个自动释放池中。

当自动释放池销毁时,会对池子内部的对象做一次release操作。仅仅是release,并不会销毁对象。

<span style="font-size:18px;">autorelease{
<span style="white-space:pre">	</span>Person *p =[ [ [Person alloc] init] autorelease];
}</span>

调用完autorelease方法后,对象的计数器不变。

好处:不用再关心对象释放的时刻,不用再关心什么时候调用release

注意点:占用内存较大的对象不要使用

由于autorelease产生的代码繁琐,因此可以创建一个类方法,用来返回autorelease。
<span style="font-size:18px;">+(id)person
{
    return [[[Person alloc] init] autorelease];
}
</span>

调用直接:
<span style="font-size:18px;">Person *p = [Person person];</span>

标注一个方法:
+(id)personWithAge:(int)age
{
    Person *p = [[[Person alloc] init] autorelease]
    p.age = age;// 将传进来的age赋值给对象p里面的age中
    return p; // 返回P
}

在main函数中一行就可以直接赋值:
把100传进p这个对象中所代表的年龄中
Person *p = [Person personWithAge:100];





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值