黑马程序员——OC基础03—内存管理

原创 2015年11月18日 11:28:45

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一、内存管理的基本管理

1.由于移动设备的内存有限,所以我们必须确保在需要的时候分配内存,在程序运行结束的时候释放占用的内存。如果只分配而不释放,就会发生内存泄漏。

2.管理的范围:只对任何继承NSObject的对象(存放堆区的),而对其他的基本数据无效。

3.原理:
对象所有权:任何自己创建的对象都归自己所有。
如果一个对象有指向其他对象的实例变量,则称该对象拥有这些对象。如果一个函数创建了一个对象,则称该函数拥有这个对象。

引用计数器:是判断对象是否要回收的依据。当一个对象没有了拥有者时,它的的引用计数器归0,此时需要回收。

当某段代码需要访问一个对象时,给系统发送retain消息,该代码将该对象的引用计数器加一,表示“我要访问该对象”。

当某段代码结束访问时,给系统发送release消息,将对象的引用计数器减一,表示不再访问该对象。

直到引用计数器的值retainCount为0时,表示不再有代码访问该对象了。因此它将被销毁,其占用的内存被系统回收以便重用。

当对象被销毁时,会调用系统的dealloc方法。但是需要重写。

重写dealloc

-(void)dealloc{

NSLog(@“XXXXX dealloc”);
[super dealloc];   //   super 的作用是访问父类的dealloc方法

Person *p1=[Person new];
[p1 retainCount]; //此时为1
Person*p2=p1;
[p2 retainCount];//此时还是为1;

分类:
MRC(手动内存管理)
ARC(自动内存管理)Xcode自动默认的。
垃圾回收

二、原则
1.
如果对象有人使用,就不应该被回收;
谁创建 谁release;
谁retain 谁release;
有始有终;
2.

内存管理的研究内容:
1)野指针: 定义指针时候没有初始化, 或则是指向的空间内容已经被释放。
2)内存泄露: 栈区的p指针已经被释放,而堆区的空间还未释放。

{

    Person *p1=[Person new];

} //此刻造成内存泄露

3.

单个对象的内存管理

如果对象已经被释放,那么这个对象称为僵尸对象;Xcode 中勾选了僵尸对象判断,则系统会报错。如果没有勾选,
被释放后的对象还是能够访问曾经指向的空间,但是此刻是以野指针访问的。

为了避免使用僵尸对象可以在对象释放后将对象指向nil。

4**set方法的内存管理**

在一个类中 存在其他的关联关系的对象,set方法书写时要release 旧值,retain新值。

-(void)setDog:(Dog*)dog{


    if(_dog!=dog){
        [_dog release];
        [_dog=dog retain ;]

    }

}

当为基本数据类型时,可以直接赋值。

  1. MRC下@property的参数

1)原子性
automic 对属性加锁
nonautomic 对属性不加锁 不安全
读写性:
readwrite 读写
readonly 可读
内存管理:
assign 直接赋值
retain release旧值 retain新值
copy

@property (nonatomic ,assign)Car* car;
如果对对象直接赋值,会造成内存泄露。
在一个类中有关联其他对象的时候用retain。



如果要替换setter和getter的名称,可以
@propertynonatomic ,setter=isVip:)
@propertynonatomic ,getter=isVip:)

6.@class 的使用
@class 类名A;
它的作用就是告诉编译器,类A只是一个类,对于类中有哪些属性和方法,不去判断检测。
好处是 当A中的内容发生了改变,不需要重新进行编译。,他可以解决循环引用的问题。

7.循环retain
循环retain会造成两个对象都发生内存泄露,为防止这种现象
1)让其中的一个对象多释放一次
2)一个对象用retain,另一个对象用assign;

三、自动释放池
1.当[p autorelease]时,会将p以栈的形式存放在栈区的释放池中,此时retainCount不变;
2.自动释放池结束时候,会给池中发送一条release消息,相当于一次release。
3.放到释放池中的代码需要手动加入到释放池[p release];才能生效。
4.autorelease的嵌套,作用域就在本代码块的区间内。

5.快速创建对象(用构造方法)

要求: 1)快速创建对象
            2)程序结束时能将对象自动释放

构建一个student类,通过重写构造方法实现创建学生对象的时候能够默认制定的年龄。

//**Person.m**
#import <Foundation/Foundation.h>

@interface Student : NSObject
@property(nonatomic,assign)int age;

-(instancetype)initWith:(int)age;
+(instancetype)studentWith:(int)age;
@end

//**Person.h**
@implementation Student
+(instancetype)studentWith:(int)age{ //instancetype 的作用要优于id,是因为前者能够智能判断赋值的指针变量的类型。

    return [[[self alloc]initWith:age]autorelease];  //自定义 且自动加入释放池

    }


-(instancetype)initWith:(int)age{

    if (self==[super init]) { //重写构造方法
        _age=18;




    }
    return self;

}
-(void)dealloc{

    NSLog(@"self dealloc");

    [super dealloc];
}
@end


//**main.m**

#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        Student*stu1=[Student studentWith:18];
        Student *stu2=[Student studentWith:20];

        NSLog(@"%d",stu1.age);
        NSLog(@"%d",stu2.age);

    }
    return 0;
}

四、ARC
1.正常创建对象,不用手动释放。
2.自动引用计数,当没有强指针指向时,ARC自动释放对象。
3.重写dealloc方法时不用写[super dealloc];
4.@property参数中没有了retain ,换成了强指针__strong 和弱指针__weak。

5.

Car *c1=[Car new];
c1=nil;
此时c1的指向发生改变,无强指针指向的空间瞬间被释放。
作用同于
__weak Car*c2=[Car new];
建立变量时候直接被释放,无效表达式。



6.ARC下的循环引用问题

strong P.dog=dog1;
Strong dog.owner= p1;
在这种情况下,即使当代码块运行结束时dog1和p1的指向都还只向着对方,仍然不会释放,造成内存泄露。
解决方案:其中一个对象设置为strong,另一个设置为weak;

Dog.h

#import <Foundation/Foundation.h>
@class Person;//避免循环引用
@interface Dog : NSObject

@property (nonatomic,strong)Person* owner;
//owner 的指针是强指针
-(void)run;

@end

Dog.m
#import "Dog.h"

@implementation Dog
-(void)run{

    NSLog(@"狗在跑。");
}

-(void)dealloc{

    NSLog(@"dog dealloc");
}
@end


 Person.h

#import <Foundation/Foundation.h>
#import "Dog.h"
@interface Person : NSObject
@property(nonatomic,strong)Dog* dog;
//dog的指针也是强指针
-(void)liuDog;
@end
@implementation Person
-(void)liuDog{

    NSLog(@"人在遛狗。");

}

-(void)dealloc{

    NSLog(@"Person dealloc");
}
@end


main.m

#import "Dog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p1=[[Person alloc]init];
        Dog*byd =[Dog new];
        p1.dog=byd;
        byd.owner=p1;
//此时两个指针互相指向对方,而且都是强指针,所以即使在ARC的情况下,当函数体结束时,两个指针及指向的空间都不会释放,造成内存泄露。
解决的方案就是将其中之一的对象的属性改为weak。


        [p1 liuDog];


    }
    return 0;
}

7.ARC中如果弱指针指向的对象不见了,则弱指针做清空操作(指向nil)。

黑马程序员_我的Linux基础整理笔记

Linux Linux文件目录和分区 文件目录: /:根目录 /root:存放root用户的相关文件 /home:存放普通用户的相关文件 /bin:存放普通用户的可执行命令 /sbin:...
  • zhengzhongjie1990
  • zhengzhongjie1990
  • 2014年07月05日 17:08
  • 1515

黑马程序员——Java基础测试题

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员——Java基础测试题 第1题:以下代码哪个是正确的?为什么?   a. byte...
  • liu007004
  • liu007004
  • 2015年01月16日 12:49
  • 1371

黑马程序员——OC视频学习过程6

-----------android培训、java培训、java学习型技术博客、期待与您交流!------------  视频16: 1、为什么要引入import import引入的头文件,...
  • woxingwosu77
  • woxingwosu77
  • 2015年08月20日 15:00
  • 244

黑马程序员——Java基础---练习题

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- Java基础---练习题 1.写出程序结果class Demo { public stat...
  • liu007004
  • liu007004
  • 2015年01月19日 16:35
  • 657

黑马程序员_HTML基础

a标签
  • u013168363
  • u013168363
  • 2013年12月29日 01:14
  • 445

黑马程序员--一个为进入黑马云六的C++屌丝的28个日夜

首先我要告诉大家,我是一个在大学学了三年C++的人,可能你们会问我,学C++不是挺好的?干嘛突然间要重新学习java呢?况且C++以后的发展不也挺好吗?        我应该怎么回答你们呢?这也是我...
  • heima_hb5
  • heima_hb5
  • 2014年08月22日 08:52
  • 2401

黑马程序员:从零基础到精通的前端学习路线

随着互联网的深入发展,前端开发工程师一跃成为市场上非常抢手的人才。很多同学,包括以前做UI的、Java的、或者对于IT完全零基础的同学都想学习前端。下图是网上流传甚广的一张前端学习思维导图,很多初学者...
  • itcast_cn
  • itcast_cn
  • 2016年07月29日 14:46
  • 5118

传智 刘意 2015年Java基础视频-深入浅出精华版 笔记 day24~day26(2016年4月26日13:11:30)

day24 1.多线程(JDK5之后的Lock锁的概述和使用)   Lock:           void lock(): 获取锁。           void unlock():释放锁。 ...
  • juliantem
  • juliantem
  • 2016年04月15日 00:40
  • 4932

黑马程序员----0704期java基础班心得

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员----0704期java基础班心得            对于任何一个刚接触ja...
  • DreamStartDemo
  • DreamStartDemo
  • 2015年07月28日 12:49
  • 388

【备忘】传智播客黑马程序员28期JavaEE基础及就业班视频教程

资源描述及截图: 日期 课程 2016/5/23 星期一 开学典礼()     2016/5/...
  • qq_38473479
  • qq_38473479
  • 2017年06月13日 15:42
  • 454
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:黑马程序员——OC基础03—内存管理
举报原因:
原因补充:

(最多只允许输入30个字)