内存分析

静态内存分析

概念:

  • 静态内存分析是不运行程序,直接对代码进行分析
  • 根据代码的上下文的语法结构,来分析内存状况

作用:

调整环境到MRC

  • 逻辑错误:访问未初始化的变量或者野指针等;
  • 声明错误:从未使用过的对象;
  • 内存管理错误:如内存泄漏等;(MRC&ARC)

关于内存泄露

iOS内存泄露的个人经验

缺点:

  • 不一定准确,但是如果发现有提示,那么去结合上下文看一下,这里的代码是否有问题

场景演练(OC):

  • MRC 下桥接

Foundation 到 CoreFoundation框架的数据类型转换

 /** ----------> MRC 下桥接 --- Foundation 到 CoreFoundation框架的数据类型转换-------*/
// 转换方法: 直接进行强制转换, 不会移交对象内存管理权

NSString *str = [[NSString alloc] init];
CFStringRef ref = (CFStringRef)str;
NSLog(@"%@", ref);
[str release];

CoreFoundation 到 Foundation框架的数据类型转换

 /** ----------> MRC 下桥接 --- CoreFoundation 到 Foundation框架的数据类型转换-------*/
// 转换方法: 直接进行强制转换, 不会移交对象内存管理权

CFStringRef ref2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "123", kCFStringEncodingUTF8);
NSString *str2 = (NSString *)ref2;
NSLog(@"%@", str2);
CFRelease(ref2);
  • ARC 下桥接

Foundation 到 CoreFoundation框架的数据类型转换

/** ----------> ARC 下桥接 --- Foundation 到 CoreFoundation框架的数据类型转换-------*/
// 转换方法: __bridge 直接转换, 不会移交对象内存管理权
//          CFBridgingRetain == __bridge_retained , 会移交对象内存管理权

NSString *str = [[NSString alloc] init];
//    CFStringRef ref = (__bridge CFStringRef)(str);
CFStringRef ref = (__bridge_retained CFStringRef)(str);
NSLog(@"%@", ref);
CFRelease(ref);

CoreFoundation 到 Foundation框架的数据类型转换

/** ----------> ARC 下桥接 --- CoreFoundation 到 Foundation框架的数据类型转换-------*/
// 转换方法: __bridge 直接转换, 不会移交对象内存管理权
//          CFBridgingRelease == __bridge_transfer , 会移交对象内存管理权
CFStringRef ref2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "123", kCFStringEncodingUTF8);
NSString *str2 = (__bridge_transfer NSString *)(ref2);
NSLog(@"%@", str2);
  • MRC--ARC环境的切换方式

target -> build setting -> 搜索 automatic reference counting

关于Swift中使用CoreFoundation 数据类型

使用了"类型重映射"机制, 转换成为了能够自动管理内存的对象, 不需要我们手动释放

动态内存分析

动态内存分析 作用:

  • 检测程序在运行过程中是否存在内存泄露 场景演示:
  • 模拟循环引用, 测试内存泄露

Dog.h

#import <Foundation/Foundation.h>
#import "Person.h"
@interface Dog : NSObject

@property (nonatomic, strong) Person * host ;

@end

Person.h

#import <Foundation/Foundation.h>
//#import "Dog.h" //如果采用导入,就会存在循环导入,因为Dog.h终也导入了Person.h
@class Dog;
@interface Person : NSObject

@property (nonatomic, strong) Dog * dog ;

@end

ViewController.m

#import "ViewController.h"
#import "Person.h"
#import "Dog.h"


@interface ViewController ()

@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1. 循环引用测试

    Person *person = [[Person alloc] init];
    Dog *dog = [[Dog alloc] init];
    person.dog = dog;
    dog.host = person;

    person = nil;
}

@end

动态内存分析

当出现内存泄露的时候

检测工具会出现如上的红叉

原因,出现循环引用导致的内存泄露

解决办法

将Person中的Dog对象或Dog中的Person对象改为weak修饰

results matching ""

    No results matching ""