美文网首页
instrument -内存泄漏

instrument -内存泄漏

作者: iOS打怪升级 | 来源:发表于2018-05-21 23:04 被阅读36次
    首先上图,感受下是什么样子的,采用了MRC
    image.png
    • instrument如下图


      image.png
    • 初始化控制器
        SubViewController * vc = [[SubViewController alloc] init];
        vc.view.backgroundColor = [UIColor redColor];
        [self presentViewController:vc animated:YES completion:nil];
        [vc release];
    
    
    • 控制器实现文件
    @interface SubViewController ()
    @property (nonatomic, strong)NSMutableArray * arrayMTest;
    @end
    
    @implementation SubViewController
    
    - (void)dealloc{
        [super dealloc];
        NSLog(@"%s",__func__);
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        //release test
        NSMutableArray * tempArray = [NSMutableArray new];
        self.arrayMTest = tempArray;
    //  self.arrayMTest =  [NSMutableArray new];这种写法需要  [_arrayMTest release];
        for (NSInteger i = 0; i<10000;i++ ) {
            PeopleModel * people1 = [[PeopleModel alloc] init];
            people1.name = @"zhang";
            people1.age = 1;
            [_arrayMTest addObject:people1];
            [people1 release];
        }
        [tempArray release];
    }
    
    *********** PeopleModel实现**********
    @interface PeopleModel : NSObject
    /** name */
    @property (nonatomic, copy) NSString *name;
    /** age */
    @property (nonatomic, assign) NSInteger age;
    
    @end
    
    @implementation PeopleModel
    
    - (instancetype)retain{
        return [super retain];
    }
    
    - (oneway void)release{
        [super release];
        
    }
    
    - (void)dealloc{
        [super dealloc];
        NSLog(@"%s\n",__func__);
    }
    
    
    

    *修正后文件

    - (void)dealloc{
        [super dealloc];
        [_arrayMTest release];//释放数组
        _arrayMTest = nil;
        NSLog(@"%s",__func__);
    }
    
    
    
    image.png

    解释:多次重复创建SubViewController ,然后diss释放,发现内存只增不减,原因数组中的对象没有手动释放,内存泄漏,对数组调用realse 会对其中的对象都调用release方法,同样的removeAllObjects 方法会对数组中的所有对象调用release 操作.

    敲黑板:
    • addObject 会调用对象的 retain方法
    • removeAllObjects 会调用对象的release 方法
    • 数组的release 会对其中的所有对象调用release 方法
    总结: addObject 操作永远和remove 操作应该最好对等出现,否则就可能内存泄漏,及时释放数组
    • 改造了下,方便对内存管理理解,代码如下:已测试没问题
    @interface SubViewController ()
    @property (nonatomic, strong)NSMutableArray * arrayMTest;
    @property (nonatomic, strong)NSMutableArray * array0Test2;
    @property (nonatomic, strong)NSMutableArray * array0Test3;
    @property (nonatomic, copy)NSArray * array0Test4;
    @end
    
    @implementation SubViewController
    
    - (void)dealloc{
        [_arrayMTest release];
        _arrayMTest = nil;
        [_array0Test2 release];
        _array0Test2 = nil;
        [_array0Test3 release];
        _array0Test3 = nil;
    /*_array0Test4 不管是否手动释放,都不会内存泄漏,请思考为什么,下面会给出解释;建议还是手动释放,从内存管理语法层面还是写上去比较好;才采用静态分析的时候会给出错误的提示*/
       // [_array0Test4 release];
       // _array0Test4 = nil;
        
        NSLog(@"%s",__func__);
        [super dealloc];
       
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        //release test
        NSMutableArray * tempArray = [NSMutableArray new];
       
        self.array0Test2 = tempArray;
        self.array0Test3 = tempArray;
        self.array0Test4 = tempArray;
        NSLog(@"%ld",_array0Test2.retainCount);
        self.arrayMTest = tempArray;
        NSLog(@"%ld",_arrayMTest.retainCount);
        for (NSInteger i = 0; i<10000;i++ ) {
            PeopleModel * people1 = [[PeopleModel alloc] init];
            people1.name = @"zhang";
            people1.age = 1;
            [_arrayMTest addObject:people1];
            [people1 release];
        }
        [tempArray release];
    }
    
    


    下面分析为啥上面的不需要手动释放instrument也不会出现内存泄漏的问题

    请仔细看代码self.array0Test4 = tempArray; 这里其实是copy 生成了一个指定空数组的指针,把带改造一下,在self.array0Test4 = tempArray;之前加一句NSArray * test = [NSArray new];会发现test 和array0Test4 指定的内存地址相容,引申一下所有的 [NSArray new]生成的内存都是同一块。这是系统优化的结果。打印array0Test4 的内存引用计数,结果输出为-1

    总结:关于空的不可变数组(NSArray,或者NSDictionary),可以不释放,因为最终系统会维护这一块地址的释放,性能检测不会提示有内存泄漏

    相关文章

      网友评论

          本文标题:instrument -内存泄漏

          本文链接:https://www.haomeiwen.com/subject/brzqjftx.html