拷贝与内存管理

一、关于深拷贝和浅拷贝的总结

理解

  • 本质上我认为区别在于复制是是指针复制(浅拷贝)还是复制到新的地址上(深拷贝)

实际应用(yltest中有具体代码)

*  大体上会区分为对象和容器两个概念,对象的copy是浅拷贝,mutablecopy是深拷贝。
  - 容器包含对象的拷贝,无论是copy,还是mutablecopy都是浅拷贝,要想实现对象的深拷贝,必须自己提供拷贝方法
  - 非容器不可变对象:NSString
  
   ```

    1. 对于非容器不可变对象的copy为浅拷贝,mutableCopy为深拷贝
    2. 浅拷贝获得的对象地址和原对象地址一致, 返回的对象为不可变对象
      3. 深拷贝返回新的内存地址,返回对象为可变对象
    
   ```
   
  - 非容器可变对象: NSMutableString
  
  ```
   对于可变对象的的拷贝,无论是copy还是mutabelCopy,都为深拷贝,且拷贝后返回的对象也是可变的
  ```
  - 容器类不可变对象: NSArray

  ```
  1.容器类不可变对象 copy只是指针copy ,mutableCopy,容器内是地址重新copy是深拷贝
  2.但是容器内的对象无论是可变与不可变对象都是浅拷贝
     
  ```
  - 容器类可变对象: NSMutableArray

    ```
  1.容器类可变对象 copy和mutableCopy是深拷贝
  2.但是容器内的对象无论是可变与不可变对象都是浅拷贝
     
  ```
小结:copy: 对于可变对象为深拷贝,对于不可变对象为浅拷贝; mutableCopy:始终是深拷贝,所谓拷贝,本质上是持有指针(无论是新的地址还是原来的地址);此外对可变容器赋值时,如果没有使用copy进行赋值,者修改其中一个内容时,其他内容会被修改(思考方向可以从引用指针和引用指针计数上开始)。不可变容器则不受影响.

自定义类对象的深浅拷贝

 在OC中不是所有的类都支持拷贝,只有遵循<NSCopying>才支持copy,只有遵循<NSMutableCopying>才支持mutableCopy。如果没有遵循,拷贝时会直接Crash。
 遵守协议以后,无论是copy还是mutableCopy,对于对象而言都是深拷贝;对对象内的属性重新赋值,不会改变其他对象的属性的值,因为赋值本质上来说是赋予新对象的属性指针
 
 ###关于属性得补充
 
 ```
 @property (nonatomic ,strong) NSArray *array;
 
    -(void)propertyTest {
NSArray *array = @[ @1, @2, @3, @4 ];
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:array];
self.array = mutableArray;
NSLog(@"array :%@, mutableArray: %@,array object_p: %p,object_p: %p",self.array ,mutableArray,self.array ,mutableArray);
[mutableArray removeAllObjects];
NSLog(@"array :%@, mutableArray: %@,array object_p: %p,object_p: %p",self.array ,mutableArray,self.array ,mutableArray);

}

 ```
 
 结果
 
 ```
 2018-03-02 11:57:28.028222+0800 YLAudioFrequecy[1446:2312615] array :(
1,
2,
3,
4

), mutableArray: (
1,
2,
3,
4
),array object_p: 0x144d8d150,object_p: 0x144d8d150
2018-03-02 11:57:28.028532+0800 YLAudioFrequecy[1446:2312615] array :(
), mutableArray: (
),array object_p: 0x144d8d150,object_p: 0x144d8d150
```
如果没有使用[mutableArray copy](深拷贝);而直接使用self.array = mutableArray;因为实际上array是被赋值了mutable属性;
移除时值会被消除;

二、内存泄漏的一些想法

  总的来说,我认为内存泄漏的原因是由于内存在ARC环境下没有被系统自动释放(如循环引用)

记录如何调试内存泄漏的blog

内存之定时器

  我们都知道定时器使用完毕时需要将其停止并滞空,但**置空定时器**方法到底何时调用呢?在当前类的dealloc方法中吗?并不是,若将置空定时器方法调用在dealloc方法中会产生如下问题,**当前类销毁执行dealloc的前提是定时器需要停止并滞空**,**而定时器停止并滞空的时机在当前类调用dealloc方法时**,这样就造成了互相等待的场景,从而内存一直无法释放。因此需要注意**置空定时器**的调用时机从而避免内存无法释放,可以将**置空定时器**方法外漏,在外部调用即可。

内存之block

   Block的内存泄漏主要是由于循环引用;防止内存泄漏就是要防止对象之间引用的闭环出现;
   一般采用的方法是让其中一个对象持有另一个对象的弱引用,例如:
   
   ```
   __weak typeof(self) weakself = self; 
   ```

内存泄漏之delegate

   ```
   @property (nonatomic, weak) id<****delegate> delegate;
   
   ```
   比较值得注意的是swift中的协议要继承与class的,这时候可以用weak来修饰

特别之非OC对象

   CGImageRef类型变量非OC对象,其需要手动执行释放操作

CGImageRelease(ref),否则会造成大量的内存泄漏导致程序崩溃。其他的对
于CoreFoundation框架下的某些对象或变量需要手动释放、C语言代码中的
malloc等需要对应free等都需要注意。

地图之内存泄漏

   若项目中使用地图相关类,一定要检测内存情况,因为地图是比较耗费

App内存的,因此在根据文档实现某地图相关功能的同时,我们需要注意内存
的正确释放,大体需要注意的有需在使用完毕时将地图、代理等滞空为nil,注
意地图中标注(大头针)的复用,并且在使用完毕时清空标注数组等。

循环数量巨大时内存管理

   ```

   for (int i = 0; i < 100000; i++) {

    @autoreleasepool {

        NSString *string = @"Abc";

        string = [string lowercaseString];

        string = [string stringByAppendingString:@"xyz"];

        NSLog(@"%@", string);

    }

}

   ```

在循环中创建自己的autoReleasePool,及时释放占用内存大的临时变量,减少内存占用峰值。

三、Xcode中将图片放入assets.xcassets和直接拖入的区别

  • 在mainBundle里面Xcode会生成一个Assets.car文件,将我们放在Images.xcassets的图片打包在里面。这里会有压缩,但是直接拖入(相当于直接将图片放入了mainBundle里面)的不会有压缩,所以程序打包出来会大一点
  • 无论是通过imageNamed:来加载图片,还是直接在Storyboard的UIImageView里面设置图片,并且无论图片是jpg格式还是png格式,都不需要写后缀名;而拖入的图片:如果在Storyboard的UIImageView设置图片,那么需要明确地写上后缀名。(无论是.png还是.jpg都要写)在使用imageNamed:加载图片时,如果是.png格式,则不需要使用后缀名;如果是.jpg格式,则必须要写上后缀名。
  • 放在Images.xcassets的图片不能通过imagesWithContentsOfFile:来加载。(因为这个方法相当于是去mainBundle里面找图片,但是这些图片都被打包进了Assets.car文件)
  • 存放在.xcassets更方便与资源管理,例如更换图片时并需要修改名称,只需要简单的替换图片资源即可。
  • 无需为不同像素的图片分别明明,系统会自动排列并且自动选择相应的图片。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容