OC语法--内存管理及对象拷贝

引用计数

readwrite:是可读可写特性,需要生成getter和setter方法;
readonly是之都特性,只会生成getter方法,不会生成setter方法,不希望属性在类外改变时候使用;
alloc 对象分配后引用计数为1retain 对象的引用计数+1
copy 一个对象变成新的对象(新内存地址) 引用计数为1 原来对象计数不变
assign:是赋值特性,setter方法将传入参数赋值给实例变量(一把钥匙,同进同出);用于基础数据类型;
weak:由ARC引入的对象变量的属性,比assign多了一个功能,对象消失后把指针置为nil,避免了野指针(不是null指针,是指向“垃圾”内存(不可用的内存)的指针);
retain:表示持有特性,setter方法将传入参数先保留,后赋值(两把钥匙,各自进出),传入参数的retaincount加1;
strong:ARC引入,等同于retain;
copy:表示赋值特性,setter方法将传入对象复制一份;需要完全一个新的对象时候(两套房子,两把钥匙);
nonatomic:非原子操作,决定编译器生成setter和getter方法是否原子操作,不加同步,多线程访问提高性能,
__unsafe_unretain:对象引用不会加1,对象释放后,不会置为nil,可能造成野指针,尽量少用。
autorelease:对象引用计数-1 如果为0不马上释放,最近一个个pool时释放

内存管理总结

大道至简
如果创建了一个对象使用了 alloc 、copy[mutable]、retain,那么你就有义务向这个对象发送一条release或者autorelease消息。

对象的拷贝copy

深浅复制对象基本概念
浅复制只复制对象的本身,对象里的属性、包含的对象不做复制。
深复制即复制对象本身,对象的属性也会复制一份
Foundation框架中支持复制的类,默认是浅复制
retain 指针引用

浅 复 制:在复制操作时,对于被复制的对象的每一层复制都是指针复制。

   深 复 制:在复制操作时,对于被复制的对象至少有一层复制是对象复制。

   完全复制:在复制操作时,对于被复制的对象的每一层复制都是对象复制。

可变数组是指针数组?????不可变数组复制只是对象的指针改变,元素指针地址没有变(待证实)
自定义类型 不相同
foundation框架默认支持拷贝协议的对象由于系统优化,无论进行深浅拷贝,不会开辟新内存(仅仅是retain了一下),不会复制,前提他是不可变对象,不调用mutableCopy。

copy,mutableCopy和retain 之间的关系
Foundation可复制的对象,当我们copy的是一个不可变的对象时,他的作用相当于retain(Cocoa做的内存优化)
当我们使用mutableCopy时,无论源对象是否可变,副本是否可变的,并且实现了真正意义上得拷贝
当我们Copy的是一个可变对象时,副本对象是不可变的,同样实现了真正意义上得拷贝

所有属性通过点语法复制,都会拷贝一份新的对象出来
@property(nonatomic,copy)Engine*engine;
copy和retain的区别是copy出一块新的内存

什么时候用到深浅拷贝??

深拷贝是在要将一个对象从可变(不可变)转为不可变(可变)或者将一个对象内容克隆一份时用到;

浅拷贝是在要复制一个对象的指针时用到。

深层拷贝不会增加原对象引用计数的

引用计数>=1时才能对对象进行操作

实例程序:。

#import <Foundation/Foundation.h>

/**

 深复制:要改

 浅复制:不改 

 copy : 对于不可变对象是浅拷贝,对于其他对象都是深拷贝

 mutablecopy:对于所有的对象都是深拷贝

 最常用的也是避免不必要麻烦的就是当开发中遇到临时变量是可变的,而成员变量是不可变的情况下,

 应该使用copy,会很安全

 

 */

void M2M()

{

    //从一个M(可变)复制到另外一个M(可变)

    NSMutableString *strM = [NSMutableStringstringWithString:@"123"];

   NSMutableString *str1 = [strMcopy];

    

   NSLog(@"%@ %@", strM, str1);

   NSLog(@"%p %p", strM, str1);

}


void M2()

{

    //从一个M(可变)复制到另外一不可变

    NSMutableString *strM = [NSMutableStringstringWithString:@"123"];

   NSString *str1 = [strMcopy];

    

   NSLog(@"%@ %@", strM, str1);

   NSLog(@"%p %p", strM, str1);


    //如果直接修改指针,是可以通过id的方式间接修改,不安全

   NSString *str2 = strM;

   NSLog(@"%@ %@", strM, str2);

   NSLog(@"%p %p", strM, str2);

    // M & !M

   NSLog(@"%@", [str2class]);

   id str3 = str2;

   NSLog(@"%@", [str3class]);

    

//    NSLog(@"%p %p", str3, str2);

    [str3setString:@"hello"];

//

   NSLog(@"%@", str2);

}


void N2M()

{

   NSString *str =@"hello";

    // copy原模原样的复制

   NSMutableString *strM = [strcopy];

//    [strM appendString:@" 123"];

    

    // mutableCopy复制出一个可变的家伙

   NSMutableString *strM1 = [strmutableCopy];

    [strM1appendString:@" 123"];

    

   NSLog(@"%@ %@ %@", str, strM, strM1);

   NSLog(@"%p %p %p", str, strM, strM1);

}


void N2N()

{

   NSString *str =@"hello";

   NSString *str1 = [strcopy];

   NSString *str2 = [strmutableCopy];

    

   NSLog(@"%@ %@ %@", str, str1, str2);

   NSLog(@"%p %p %p", str, str1, str2);

}


void Person2Person()

{

   Person *p = [[Personalloc]init];

    p.name =@"zhang";

   Person *p1 = [pcopy];

    p1.name =@"li";

    

   NSLog(@"%@ %@", p, p1);

   NSLog(@"%p %p", p, p1);

}


int main(int argc,constchar * argv[])

{

    @autoreleasepool {        

        

       M2();

        

    }

   return0;

}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值