OC基础语法学习5:内存管理(手动管理)

本文详细介绍了Objective-C中的对象创建过程、内存管理原则、避免野指针操作和内存泄漏的方法,并通过实例展示了set方法及@property参数的内存管理分析。

1、一个对象的创建的过程:

[[类 alloc]init];

1、先分配内存空间,存储对象
2、初始化成员变量
3、返回对象的指针地址

对象在创建的同时,内部会自动创建一个引用计数器,这个引用计数器是系统用来判断对象回收的唯一依据。当引用计数器为retainCount = 0时,系统会自动调用dealloc函数,将对象销毁。

[对象 retain]; // retainCount + 1
[对象 release]; //retainCount - 1

2、内存管理的原则:

只要出现了new alloc retain就一定要有对应的 release autorelease 出现。

3、手动内存管理研究的主要问题:

1、野指针操作:是指该指针指向的内存空间已经不存在了,该指针也没有赋值为 nil,对该指针继续进行操作。
2、内存泄漏:不再使用的对象一直存在内存中。

4、避免野指针操作的方法:

内存空间释放完毕之后的指针一定要赋值为 nil

5、避免内存泄漏的操作方法:

遵守内存管理的配对原则。

例子:
.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (void)run;

@end

.m文件


#import "Person.h"

@implementation Person
//该函数在对象接到release消息时由系统自动调用的
-(void)dealloc
{
    //在对象自身被销毁之前,一定要先调用[super dealloc]释放父类中的相关对象
    [super dealloc];
    NSLog(@"Person 被销毁了");
}


- (void)run
{
    NSLog(@"人跑起来了");
}
@end

main.m

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        // 1
        Person * p = [[Person alloc] init];

        NSLog(@"%lu",p.retainCount);

        // 2
        [p retain];

        NSLog(@"%lu",p.retainCount);

        // 1
        [p release];

        NSLog(@"%lu",p.retainCount);

        //0
        [p release];
        p = nil;

 }

6、set方法的内存管理分析
car.h

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property int speed;

- (void)run;

@end

Car.m


#import "Car.h"

@implementation Car

- (void)dealloc
{
    [super dealloc];
    NSLog(@"Car 被销毁了 %d速度",_speed);
}

- (void)run
{
    NSLog(@"汽车跑起来了");
}

@end

Person.h

#import <Foundation/Foundation.h>
#import "Car.h"

@interface Person : NSObject
{
    Car * _car;
    NSString * _name;
}

- (void)setName:(NSString *)name;
- (NSString *)name;

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

- (void)drive;

@end

Person.m

#import "Person.h"

//配对原则:new alloc retain 对应一个release,autorelease

@implementation Person

- (void)setName:(NSString *)name
{
    if (_name != name)
    {
        [_name release];
        _name = [name retain];
    }

}
- (NSString *)name
{
    return _name;
}
//面试笔试,出题率非常高
- (void)setCar:(Car *)car
{

    if (_car != car)
    {  
        [_car release];  //第一个Car对象进入是执行[nil release];
        _car  = [car retain];
    }

}
- (Car *)car
{
    return _car;
}

- (void)drive
{
    [_car run];
}
- (void)dealloc
{
    //目的是要保证在p对象存在的时候,car对象一定存在
    [_car release];
    [_name release];
    [super dealloc];
    NSLog(@"Person 被销毁了");
}

@end

7、@property参数的内存管理分析

7.1、@property 的3个作用:

- 生成set与get方法的声明
- 生成set与get方法的简单实现
- 如果没有相对应的成员变量,会自动生成_开头的成员变量

7.2、@property参数分为4类

 1、与set方法内存管理相关的参数
 retain:要生成符合内存管理原则的set方法(应用于对象)
     @property (nonatomic,retain) Car* car;
 assign: 直接赋值(对象类型,基本数据类型)
     @property (nonatomic,assign) int age;
   copy:拷贝

2、多线程相关
    nonatomic:不生成多线程管理代码,(效率高)
    @property (nonatomic ,retain) NSString * name;
    atomic:生成多线程管理代码(不写默认就是这种方式)
    实际开发中都用nonatomic
3、是否要生成set与get方法
    readwrite:可读可写属性,同时生成set和get方法
    readonly:只读属性,只生成get方法
    @property (nonatomic,assign,readonly)int idCard;
4、set与get方法名称相关的参数
    setter:设置生成的setter方法名称
    getter:设置生成的get方法名称
    @property (nonatomic,assign,setter = isDeid:,getter = isDeid)BOOL isDeid;

注意:

如果一个对象被生成了成员变量或者使用了@property生成了符合setter的内存管理方法,那么在dealloc函数对应一次release的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值