黑马程序员_iOS_OC_内存管理

原创 2015年11月19日 14:16:34

 ——- android培训java培训、期待与您交流! ———-
1.内存管理的基本概念及范围
管理范围:管理任何继承NSObject的对象。
2.内存管理的原理及分类
1)对象的所有者及引用计数
只要一个对象至少还有一个所有者,就继续存在。

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

引用计数器是判断对象要不要回收的依据。
关键字:alloc,new,copy,retain,release,retainCount
2)OC内存管理分类
MRC:retain,release,autorelease
ARC
垃圾回收

/*
    引用计数器:
        用来保存当前对象有几个东西在使用它
    引用计数器作用:
        用来判断对象是否应该回收内存空间
    引用计数器的操作:
        retain:引用计数器+1
        release:-1
        retainCount:引用计数器当前值
    一个对象被释放的时候会调用dealloc方法(NSObject),需要重写。
    手动管理内存
        ARC改为MRC

 */


#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        NSInteger count = [p retainCount];
        NSLog(@"%lu",count);
        Person *p2 = [p retain];//需要retain
        NSLog(@"%lu",[p2 retainCount]);
        //retainCount = 0才能回收
        [p release];
        NSLog(@"%lu",[p retainCount]);
        [p release];//p即将被销毁  Person重写dealloc方法


    }
    return 0;
}

#import "Person.h"

@implementation Person

//系统根据引用计数器的值自动调用
-(void)dealloc
{
    //先释放子类空间,再释放父类
    NSLog(@"Person销毁");

    [super dealloc];
}
@end

3.内存管理的原则

/*
内存管理
    对象如果不再使用,回收他的内存空间,防止内存泄漏
内存管理范围
    所有继承了NSObject的对象,基本数据类型不需要(包括结构体和枚举)
内存管理的原则
    只要有人使用就不能被回收。
    使用对象引用计数器+1//retain
    使用完-1//release
    谁创建谁release
    谁retain谁release
内存管理研究内容
    野指针:1)定义的指针变量没有初始化 2)指向的空间被释放
    内存泄漏:如果栈区的引用被释放而堆区的空间没有释放,堆区内存泄漏
 */


#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //谁创建谁release
        Person *p = [[Person alloc] init];//1
        NSLog(@"%lu",[p retainCount]);
        Person *p2 = [p retain];//2
        NSLog(@"%lu",[p2 retainCount]);
        [p release];//1

        [p release];//0
    }
    return 0;
}

4.单个对象内存管理(野指针)

/*

 nil是一个对象值

 NULL一个通用指针

 不能使用僵尸对象



 */
#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //对象创建完成后默认所有者有一个,自己,引用计数为1
        Person *p = [Person new];//1
        [p eat];
        NSLog(@"%lu",p.retainCount);
        [p release];//0
//        NSLog(@"%lu",p.retainCount);   属于野指针访问
        //如果一个对象被释放,称为僵尸对象
        //enable zombie objects  开启检测僵尸对象
        //p 为野指针
        [p eat];//只被登记为无人使用,默认情况下不报错  属于野指针访问
    }
    return 0;
}

5.单个对象的内存管理
1)避免使用僵尸对象
2)对象内存泄漏

#import <Foundation/Foundation.h>
#include "Person.h"
void test()
{
    Person *p = [Person new];//1


    [p release];//0
    //避免使用僵尸对象,对象释放后给对象赋值为nil
    p = nil;

    //给nil发送任何信息都没有效果
    //        [nil run];

    [p retain];
}

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

        //当个对象的内存泄漏问题
        //情况1:创建完成后没有release内存泄漏
//        Person *p = [Person new];//如果不release,内存泄漏
//        NSLog(@"%lu",p.retainCount);
//        [p eat];
        //情况2:没有遵守内存管理原则
//        [p retain];
//        [p release];
//        [p release];
        //情况3:不但使用nil
        Person *p = [Person new];
        p = nil;
        [p release];

        //情况4:函数内部对传入的对象retain

    }//p被释放,内存泄漏
    return 0;
}

6.多个对象内存管理(野指针)

#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];//1
        Car *c = [Car new];//1

        [c setSpeed:100];
        [p setCar:c];
        [p go];

        [c release];//0
//        [p go];//c对象已经被销毁
        [p release];//0
    }
    return 0;
}

8.多个对象的内存管理(内存泄漏)


#import "Person.h"

@implementation Person
-(void) go
{
    [_car run];
}
-(void) setCar:(Car *)car
{
    _car = [car retain];//retain一次
}

-(void) dealloc
{
    [_car release];//release一次
    //self.car = nil;
    NSLog(@"%s",__func__);
    [super dealloc];
}
@end

9.set方法的内存管理问题

#import "Person.h"
@implementation Person
-(void) go
{
    [_car run];
}
//set方法的内存管理原则:
//如果在一个类中,有其他类的对象(关联关系)
//set方法书写的时候要判断是否是同一个对象,release旧值,retain新值
-(void) setCar:(Car *)car
{
    if (_car != car) {
        [_car release];//[nil release];
        _car = [car retain];//retain一次 2
    }
}
-(void) dealloc
{
    [_car release];//release一次
    //self.car = nil;
    NSLog(@"%s",__func__);
    [super dealloc];
}
@end

10.set 方法内存管理总结

//基本数据类型的数据作为实例变量
//int  _speed;
//set方法的写法
-(void) setSpeed:(int) speed
{
    _speed = speed;
}
//Dog *_dog
//对于对象作为另一个类的实例变量
-(void)setDog:(Dog *)dog
{
    //判断是斗士原对象
    if(_dog != dog){
        //release旧值
        [_dog release];
        //retain新值,并赋值给_dog
        _dog = [dog retain];
    }
}

11.@property参数
@property int age;
1)生成_age
2)生成_age的get和set方法的声明
3)实现_age的get和set方法
格式:@property (参数1,参数2) 数据类型 方法名
原子性:atomic,nonatomic
读写属性:readwrite,readonly
set方法处理:assign,retain,copy

/*
@property参数
 三类 七个
 原子性:atomic,nonatomic
 读写属性:readwrite,readonly
 set方法处理:assign,retain,copy(内存管理)

 什么时候使用retain
 在一个类中关联其他对象的时候

 什么时候使用assign
 实例变量是基本数据类型的时候
 */
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
@property (nonatomic,assign) int age;//assign直接赋值
@property (nonatomic,retain) Car *car;//retain  release旧值   retain新值
@end

11.@property参数的使用二

#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
//默认生成set和get方法
@property (nonatomic,assign) int age;
@property (nonatomic,assign,setter=isVip:,getter=isVip) BOOL vip;
@end

13.@class的使用

/*
 @class使用格式
    @class的使用格式:@class 类名;
    告诉编译器是一个类名,不检测属性方法
    好处:如果文件内容发生改变不需要重新编译
 @class使用注意
    1).h  @class xx
    2).m  #import "xx.h"
 @class 解决循环引入问题
 */

14.循环retain问题

/*
循环retain会导致两个对象都会泄漏内存
防治方法:
1)让某个对象对释放一次
2)一端使用assign,一端使用retain(推荐)
*/

15.NSString类的内存管理问题
大部分都是存在于常量区,不需要我们管理。
16.autorelease基本使用

/*
 自动释放池
 以栈结构存在
 对象可以加入到自动释放池中,自动释放池结束的时候会给池中的对象发送一条release消息
 调用autorelease时,将对象放入栈顶的释放池
 1)创建释放池
 2)加入自动释放池  [对象 autorelease];
 */
#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    Person *p = [Person new];
    @autoreleasepool {
        [p run];
        [p autorelease];
        [p run];
    }//对象释放
    [p run];
    return 0;
}

16.autorelease注意及错误用法
注意:
1)并不是将对象放到自动释放池代码中,都会自动加入到自动释放池。

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

//      Person *p = [Person new];

//    自动释放池
    @autoreleasepool {

        //并不是放到自动释放池代码中,都会自动加入到自动释放池。
        //如果需要释放,必须加入自动释放池
        Person *p = [[Person new] autorelease];

//        对象在池内部外部创建都可以,只要是在池中调用autorelease
//        [p autorelease];//加入释放池
    }
//    此时p不在自动释放池
//    
//    Person *p = [[Person new] autorelease];

    return 0;
}

2)自动释放池的嵌套使用

#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    Person *p = [Person new];
    [p retain];
    //autorelease嵌套
//    自动释放池的栈结构和内存的栈不一样
    @autoreleasepool {
        @autoreleasepool {
            @autoreleasepool {
                [p autorelease];
                [p autorelease];//在同一个释放池不要使用两次autorelease
            }
            [p autorelease];
        }//在此处销毁
    }
    return 0;
}

3)自动释放池不适宜放占用内存过大的对象
17.autorelease的应用场景
创建对象同时管理内存

#import "Person.h"
@implementation Person
+(id) person
{
    //创建对象
    //加入自动释放池
    return [[[Person alloc] init] autorelease];

}
-(void) dealloc
{
    NSLog(@"%s",__func__);
    [super dealloc];
}
-(void) run
{
    NSLog(@"%s",__func__);
}
@end
#import <Foundation/Foundation.h>
#include "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        [p autorelease];
        //1)创建一个对象
        //2)用完之后,系统把对象释放掉
        Person *p1 = [Person person];
    }
    return 0;
}

黑马程序员-IOS基础之OC内存管理

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 内存管理 01、为什么要内存管理?        内存管理可谓是OC里...

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

ARC的判断准则:只要没有强指针指向对象,
  • kldxcr
  • kldxcr
  • 2014年04月04日 22:56
  • 827

黑马程序员--ios基础--oc内存管理

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 第一讲 结构体 int main(int argc, const char * argv[])...
  • yuanptt
  • yuanptt
  • 2015年05月13日 14:17
  • 303

黑马程序员-----------ios培训 oc内存管理(一)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 一.对象的基本结构 1.引用计数器:被引用的次数,占用四个字节,当使用alloc 、new、c...

黑马程序员——ios开发基础之OC内存管理与blocks

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 第一讲    内存管理 1. 内存管理概念理解           1)内存管理的范围     ...

黑马程序员—(iOS开发)OC内存管理机制---(十)

------- android培训、iOS培训、Java培训、.NET培训期待与您交流! ----------   ------- android培训、iOS培训、Java培训、...

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

栈中的数据系统自动回收 堆空间中的数据动态分配,不能自动分配,容易引起...
  • kldxcr
  • kldxcr
  • 2014年04月03日 22:30
  • 582

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

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——一、OC内存管理基本概念 因为手机的内存有限,为了保证每个程序能正常运行,要对内存进行管理。当内存不再使用的时...

黑马程序员—IOS加强视频—oc内存管理

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- .堆:存放的是一些动态分配的对象/类,系统是不会自动回收这些内存的 栈:存放的是一些...

ios黑马程序员--oc内存管理

内存管理概念 对象在内存中使用玩之后 拿iphone 4;来说 512M内存 什么时候创建,什么时候回收 创建对象的时候retainCount = 1;只读的;引用计数器;记录有多少人...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:黑马程序员_iOS_OC_内存管理
举报原因:
原因补充:

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