OC基础-内存管理

<1>内存管理的概念:由于移动设备的内容极其有限,所以对其中无用的内存空间要进行及时回收,这称为内存管理。

内存管理的范围:所有继承至NSObject的对象,其中基本数据类型由系统自动进行管理。

内存管理的原理:当在栈区定义类的实例变量后,该变量就是该实例变量的一个所有者。实例化的类对象中有retainCount变量,

称为对象的引用计数器。当引用计数器为0时,就会调用对象的dealloc方法进行对象内存空间的释放。

内存管理的分类:(1)ARC(AutoReferenceCounting):自动内存管理;(2)MRC(ManualReferenceCounting):手动内存管理;

在MRC下,可以通过对象的retain方法使retainCount增加1,release方法使retainCount减少1;当对象释放其所占用的内存空间时,

会自动调用自身的dealloc方法,可以在NSObject中重写dealloc方法。

<2>内存管理的原则:(1)谁创建,谁release;(2)谁retain,谁release。(2)只要存在对象的所有者,对象就不会被回收。

内存管理研究的内容:(1)野指针。当指针变量未初始化,或者指针变量所指向的内存空间被释放时,都会出现野指针。(2)内存泄露:

栈区的变量已经释放,而堆区的内存空间未释放时,就会出现内存泄露。

<3>单个对象的内存管理:nil:指向实例对象;Nil:指向类对象;null:指向实例对象,用在不能使用nil的场所。

给nil发送任何消息都没有效果,但能通过编译器检查。

单个对象内存泄露的情况:(1)创建完成后,没有release;(2)没有遵守内存管理的原则;(3)不当的使用了nil;(4)在函数中retain.

<4>多个对象的内存管理:依赖关系的两个对象,其正确的属性setter方法如下:

@interfance Car:NSObject


@end

@interface Person:NSObject

{Car *_car;}

-(void)setCar:(Car *)car;

@end

@implementation

-(void)setCar:(Car *)car{

if(_car != car){//避免出现僵尸对象复活的错误

[_car release];//避免出现内存泄露

_car = [car retain];//避免出现僵尸对象引用的错误

}

}

@end

<5>@property的参数有三种:

(1)原子性。

atomic:对属性加锁,多线程安全,是property的默认值;nonatomic:对属性不加锁,多线程

不安全,但速度快;

(2)读写性。

readwrite:具有完整的setter和getter方法;

readonly:只有getter方法;

(3)setter方法的处理:

assign:简单地直接赋值,是property的默认方法;

retain:对实例变量先release,再retain;

copy:对实例变量先release,在retain;

可以在@property的参数中给setter或者getter方法制定别名,如

@interface Person :NSObject

@property (nonatomic,assign ,setter = isSolider: ) BOOL solider;//指定setter方法别名为isSolider;

@end

Person *p = [Person new];

[p isSolider] = YES;//在main函数中使用isSolider方法对属性进行赋值;

<6>@class的应用:简单的引用类,告诉编译器一个类对象,并不进行类属性和方法的检查。

使用注意:(1)在.h文件中 声明@class XX;(2)在.m文件中,引用#import “XX.h”;

特殊用法:可以解决#import循环引用的问题;

@class和#import的区别:

(1)作用上:@class进行类的简单引用,而#import则是把引用文件拷贝到它所在的位置;

(2)效率上:@class引用避免了引用文件修改时的及时更新,效率较高;

<7>循环retain的问题:当两个对象循环retain时,会导致内存泄露。

防止方法:(1)在执行结束时,让其中某个对象再release一次;

(2)循环retain的两方,一端使用assign,一端使用retain;

<8>NSString类的内存管理问题:用@”XX“,[NSString StringWithString:@“XX”],[[NSString alloc] init]方法定义的字符串都是

存在内存中的常量区(数据区),当在栈区定义新的字符串变量时,如果在常量区中存在,则系统不会再次分配空间,而是会将变量指向已经

存在的变量;

用[NSString StringWithFormat:@“”]方法定义的字符串变量存放在堆区,需要对其进行内存释放;

<9>autorelease的基本使用。

(1)特殊的栈结构;

(2)对象调用autorelease方法时,会被放在栈顶;

(3)当内存池排干(drain)时,会对其中的对象发送release消息。

其中内存管理的几个实例代码如下:

(1)

#import <Foundation/Foundation.h>

@interface Person : NSObject
-(void)eat;
@end
#import "Person.h"

@implementation Person
-(void)dealloc{
    NSLog(@"人已经被处理了");
    [super dealloc];
}
-(void)eat{
    NSLog(@"人在吃饭");
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
//验证内存管理的原则:谁retain,谁release
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        NSLog(@"retainCount = %ld",[p retainCount]);
        Person *p1 = [p retain];
        NSLog(@"retainCount = %ld",[p retainCount]);
        [p1 release];
        [p1 eat];
        NSLog(@"retainCount = %ld",[p retainCount]);
        [p release];
        [p eat];
    }
    return 0;
}
2
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(228, 68, 72);"><pre name="code" class="objc">#import <Foundation/Foundation.h>
#include "Car.h"
@interface Person : NSObject
{
    Car *_car;
}
-(void)setCar:(Car *) car;
-(void)drive;
@end
#import "Person.h"

@implementation Person
-(void)setCar:(Car *) car{
    if (_car != car) {
        [_car release];
        _car = [car retain];
    }
}
-(void)drive{
    [_car run];
}
-(void)dealloc{
    [_car release];
    NSLog(@"人已经挂了");
    [super dealloc];
}
@end
#import <Foundation/Foundation.h>

@interface Car : NSObject
@property int speed;
-(void)run;
@end
#import "Car.h"

@implementation Car
@synthesize speed;
-(void)run{
    NSLog(@"车以%d的速度奔跑!",self.speed);
}
-(void)dealloc{
    NSLog(@"车已经挂了");
    [super dealloc];
}
@end
//关联对象的内存管理
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        Car *car = [Car new];
        car.speed = 18;
        [p setCar:car];
        [car release];//清除car空间
        [p drive];//
        [p release];//清除person空间
        
        
    }
    return 0;
}
3

<pre name="code" class="objc" style="color: rgb(228, 68, 72); font-size: 13px;"><pre name="code" class="objc">#import <Foundation/Foundation.h>
@class Person;
@interface Dog : NSObject
@property (nonatomic,assign) Person *owner;
@end

#import "Dog.h"

@implementation Dog
-(void)dealloc{
   // [_owner release];
    NSLog(@"dog dealloc");
    [super dealloc];
}
@end
#import <Foundation/Foundation.h>
#import "Dog.h"
@interface Person : NSObject
@property (nonatomic,retain)Dog *dog;
@end
#import "Person.h"

@implementation Person
-(void)dealloc{
    [_dog release];
    NSLog(@"Person dealloc");
    [super dealloc];
}
@end
//@class避免循环引用
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        Dog *d = [Dog new];
        p.dog = d;
        d.owner = p;
        
        [p release];
        [d release];
    }
    return 0;
}


 
 
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(228, 68, 72);">
</p>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值