内存管理高级

内存管理高级

内存管理高级:

1.属性的内部实现原理

2.dealloc内释放实例变量

3.便利构造器方法的实现原理

4.collection的内存管理

name, age, gender

自定义初始化方法

便利构造器

Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject <NSCopying>
//重在对象, 使用retain; 重在内容, 使用copy
@property (nonatomic, retain) NSString *name;
@property (nonatomic) NSInteger age;
@property (nonatomic, copy) NSString *gender;
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender;
+ (instancetype)studentWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender;
@end
Student.m
#import "Student.h"
@implementation Student
@synthesize name = _name, age = _age, gender = _gender;
#pragma mark - liftCycle
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender {
    if (self = [super init]) {
        //1
        _name = [name retain];
        _age = age;
        _gender = [gender copy];
        //2
        self.name = name;
        self.age = age;
        self.gender = gender;
    }
    return  self;
}
+ (instancetype)studentWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender {
    return [[[Student alloc] initWithName:name age:age gender:gender] autorelease];
}

- (void)dealloc {
    [_name release];
    [_gender release];
    [super dealloc];
}
#pragma mark - super
- (NSString *)description
{
    return [NSString stringWithFormat:@"name:%@ age:%ld gender:%@", _name, _age, _gender];
}

#pragma mark - accessor
- (void)setName:(NSString *)name {
    if (_name != name) {
        [_name release];
        _name = [name retain];
    }
}
- (NSString *)name {
    return _name;
}
- (void)setAge:(NSInteger)age {
    _age = age;
}

- (NSInteger)age {
    return _age;
}
- (void)setGender:(NSString *)gender {
    if (_gender != gender) {
        [_gender release];
        _gender = [gender copy];
    }
}
- (NSString *)gender {
    return _gender;
}
#pragma mark - NSCopying
-(id)copyWithZone:(NSZone *)zone {
    //浅拷贝
//    return [self retain];

    //深拷贝
    //1.复制结构
    Student *student = [[Student allocWithZone:zone] init];
    //2.复制内容
    student.name = self.name;
    student.age = self.age;
    student.gender = self.gender;
    return student;
}
@end
main.m
        Student *stu1 = [[Student alloc] initWithName:@"张三" age:18 gender:@"男"];
        NSLog(@"%@", stu1);
        //想要对stu1对象做copy操作, Student类必须遵守<NSCoping>协议
        Student *stu2 = [stu1 copy];
        NSLog(@"%@", stu2);
        [stu1 release];
        [stu2 release];
        //属性的修饰词是copy
        NSMutableString *string = [[NSMutableString alloc] initWithFormat:@"zhangsan"];
        Student *student = [[Student alloc] init];
        student.gender = string;
        NSLog(@"%@", student.gender);
        [string setString:@"zhangsanfeng"];
         NSLog(@"%@", student.gender);
        [string release];
        [student release];

  针对系统的数据类型

        对不可变的数据类型, copy是浅拷贝

        NSString  *str1 = [[NSString alloc] initWithFormat:@"辉哥真帅哦哦!"];
        NSLog(@"%lu", str1.retainCount);//1
        NSString *str2  = [str1 copy];
        NSLog(@"%p", str1);
        NSLog(@"%p", str2);
        NSLog(@"%lu", str1.retainCount);//2

对可变的数据类型, copy是深拷贝 

        NSMutableString *mStr1 = [[NSMutableString alloc] initWithFormat:@"小灰灰"];
        NSLog(@"mStr1:%p", mStr1);
        //copy: 不可变拷贝, 拷贝出来不可变
        NSMutableString *mStr2 = [mStr1 copy];
        NSLog(@"mStr2:%p", mStr2);
        NSLog(@"%lu", mStr1.retainCount);//1

  copy: 不可变拷贝, 拷贝出来不可变

        对不可变的数据类型, copy是浅拷贝

        对可变的数据类型, copy是深拷贝

 mutableCopy: 可变拷贝, 拷贝出来是可变的

        对不可变数据类型可变数据类型, mutableCopy都是深拷贝

        NSMutableString *mStr3 = [mStr1 mutableCopy];
        NSLog(@"%@", mStr3);
        [mStr3 setString:@"真帅"];
        NSLog(@"%@", mStr3);
        NSString *tempName = [[NSString alloc] initWithFormat:@"无敌"];
        Student *tempStu = [[Student alloc] initWithName:tempName age:18 gender:@"男"];
        NSLog(@"%@", tempStu.name);
        [tempName release];
        NSLog(@"%@", tempStu.name);

通过便利构造器创建的对象, 不需要释放

        Student *s = [Student studentWithName:@"小明" age:18 gender:@"男"];
        NSLog(@"%@", s);

  集合中的内存管理

        1.集合会对放入到集合中的对象, 做引用计数+1的操作

        2.当对象从集合移除时, 做引用计数-1操作

        3.当集合释放时, 会对集合中的对象依次执行引用计数-1的操作 

        Student *s1 = [[Student alloc] initWithName:@"小强" age:18 gender:@"男"];
        Student *s2 = [[Student alloc] initWithName:@"小强" age:18 gender:@"男"];
        Student *s3 = [[Student alloc] initWithName:@"小强" age:18 gender:@"男"];
        NSMutableArray *array = [NSMutableArray arrayWithObjects:s1, s2, s3, nil];
        [s1 release];
        [s2 release];
        [s3 release];
        NSLog(@"%@", array);

 保留环(retainCycle): 两个对象相互保留对方, 导致这两个对象都无法得到释放

解决方案: 打破环状结构

Man.h
#import <Foundation/Foundation.h>
@class Woman;
@interface Man : NSObject
@property (nonatomic, assign) Woman *wife;
//代理delegate写成属性, 修饰词用assign, 为了避免出现保留环
//@property (nonatomic, assign) id<BaoMu> delegate;
@end
Man.m
#import "Man.h"
#import "Woman.h"
@implementation Man
- (void)dealloc {
    NSLog(@"男人释放了");
    [super dealloc];
}
@end
Woman.h
#import <Foundation/Foundation.h>
@class Man;
@interface Woman : NSObject
@property (nonatomic, retain) Man *husband;
@end
Woman.m
#import "Woman.h"
#import "Man.h"
@implementation Woman
- (void)dealloc {
    NSLog(@"女人释放了");
    [_husband release];
    [super dealloc];
}
@end
main.m
        Man *man = [[Man alloc] init];
        Woman *woman = [[Woman alloc] init];
        man.wife = woman;
        woman.husband = man;
        [man release];
        [woman release];
        
时间: 2024-08-01 10:43:54

内存管理高级的相关文章

Objective-C 内存管理高级

今天我们在内存管理初级的基础上,详细研究一下内存管理的实现过程, 我还是啰嗦一下,即使这个很枯燥,但是绝对值得让你花上一天的时间好好来理解这里面的猫腻. 一.前言 对于大多数从C++或者JAVA转过来学习Object-C(以下简称OC)的人来说,OC这门语言看起来非常奇怪,用起来也有点麻烦. OC没有像JAVA一样的垃圾回收机制,也就是说,OC编程需要程序员手动去管理内存.这就是为什么它烦的原因,苹果却一直推崇开发者在有限硬件资源内写出最优化的代码,使用CPU最少,占用内存最小. 二.基本原理

OC --(10)-- 内存管理高级:属性的内部实现原理、dealloc内释放实例变量、便利构造器方法的实现原理、collection的内存管理

【读书笔记】C#高级编程 第十四章 内存管理和指针

(一)后台内存管理 1.值数据类型 Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址,该任务由Windows在后台管理(32位每个进程可使用4GB虚拟内存,64位更多,这个内存包括可执行代码和加载的DLL,以及程序运行时使用的变量内容). 在处理器的虚拟内存中,有一个区域称为栈.栈存储不是对象成员的值数据类型. 释放变量时,其顺序总是与它们分配内存的顺序相反,这就是栈的工作方式. 程序第一次运行时,栈指针指向为栈保留的内存块末尾.栈实际上是向下填充的,即从

OC系列高级-内存管理

一.MRC 和 ARC 1.mrc模式下声明一个Dog对象 析构函数 二.mrc手动内存管理模式下get和set方法

setter 和 getter 高级 以及内存管理初级

setter 和 getter 的演变,紧接setter 和 getter 初级 [email protected] 和  @synthesize 这两个关键字的出现,就是为了剔除代码中的setter方法和getter方法 @property:可以自动生成某个成员变量的setter和getter声明 @property int age;//相当于下面这两句:- (void)setAge:(int)age;- (int)age; @synthesize自动生成age的setter和getter实现

OC 高级内存管理

// // main.m // 第8讲 // / #import <Foundation/Foundation.h> #import "teacher.h" #import "classes.h" #import "man.h" #import "woman.h" #import "Student.h" #import "Card.h" /* 类簇: 多个类的组合,多个类来实

Objective-C高级编程:iOS多线程及内存管理(第一章翻译)

写在翻译之前:当初看到这本书的时候,感觉深入浅出讲得比较到位,但是在市面上看到的翻译版本翻译的却没有原著的精髓和味道.所以产生了自己将其翻译一下给初学者一些便利的想法.所以才有了这个系列的第一章的翻译.目前剩余的部分依然在翻译过程中,估计不久之后就可以陆续地发出了. 因为本人的水平或者用词问题,本翻译难免有不周详或不正确之处.如果有人看到还望指出,我一定会尽力地修改那些不正确的部分,让更多的人可以看到更优质的资料. Chapter 1 Life before Automatic Referenc

OC系列高级-内存管理关键字

一.MRC中@property关键字 1.assign,retain,copy 这几个关键字用语setter方法的内存管理 assign:一般用于非oc对象,直接自信赋值操作 retain:一般用于oc对象,那么将retain新值,release旧值 copy:将release旧值,copy新值 一般默认是assign 2.nonatomic和atomic 这两个关键字用语多线程管理,nontomic性能高,atomic性能低,不显示使用以atomic为默认值 3.readwrite和reado

FreeRTOS高级篇7---FreeRTOS内存管理分析

内存管理对应用程序和操作系统来说都非常重要.现在很多的程序漏洞和运行崩溃都和内存分配使用错误有关.        FreeRTOS操作系统将内核与内存管理分开实现,操作系统内核仅规定了必要的内存管理函数原型,而不关心这些内存管理函数是如何实现的.这样做大有好处,可以增加系统的灵活性:不同的应用场合可以使用不同的内存分配实现,选择对自己更有利的内存管理策略.比如对于安全型的嵌入式系统,通常不允许动态内存分配,那么可以采用非常简单的内存管理策略,一经申请的内存,甚至不允许被释放.在满足设计要求的前提