内存管理

copy的内存管理

首先理解一下深复制和浅复制:

  • 深复制
    源对象和副本对象是不同的两个对象;
    源对象引用计数器不变,副本对象计数器为1(因为是新产生的);
    本质是:产生了新的对象。
  • 浅复制
    源对象和副本对象是同一个对象
    源对象(副本对象)引用计数器+1,相当于做一次retain操作;
    本质是:没有产生新对象。

注意:只有源对象和副本对象都不可变时,才是浅拷贝,其他都是深拷贝

NSString *str1 = [NSString stringWithFormat:@"address is only one"];
  NSString *str2 = [str1 copy];
  NSLog(@"%p ,%p",str1,str2);
//结果发现两个地址一样,都是0x610000052990。
/**
  1.copy:产生的肯定是不可变副本
  2. 如果是不可变对象调用copy方法产生出不可变副本,那么不会产生新的对象 
*/

1. NSMutableString调用mutableCopy : 深复制。
2. NSMutableString调用copy : 深复制。
3. NSString调用mutableCopy : 深复制。
4. NSString调用copy : 浅复制
__strong

当一个对象被强指针指向则引用计数就加1,否则,该对象没有一个强指针指向则自动释放内存

原理:

__weak
    id __weak obj = [[NSObject alloc] init];

可以知道NSObject对象在生成之后立马就会被释放,其主要原因是__weak修饰的指针没有引起对象内部的引用计数器的变化

原理:

  • 修饰的指针不会引起指向的对象的引用计数器变化
    id obj;
    id tmp = objc_msgSend(NSObject,@selector(alloc));
    objc_msgSend(tmp,@selector(init));
    objc_initweak(&obj,tmp);
    objc_release(tmp);
    objc_destroyWeak(&object);

对于__weak内存管理也借助了类似于引用计数表的表,它通过对象的内存地址做为key,而对应的指针作为value进行管理,在上述代码中objc_initweak就是完成这部分操作,而objc_destroyWeak
则是销毁该对象对应的value。所以,weak在修饰只是让weak表增加了记录没有引起引用计数表的变化

  • 当指向的对象被销毁时,弱指针全部置为nil
    原理:
    1)从weak表中获取已废弃对象内存地址对应的所有记录
    2)将已废弃对象内存地址对应的记录中所有以weak修饰的变量都置为nil
    3)从weak表删除已废弃对象内存地址对应的记录
    4)根据已废弃对象内存地址从引用计数表中找到对应记录删除
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容