内存分析
静态内存分析
概念:
- 静态内存分析是不运行程序,直接对代码进行分析
- 根据代码的上下文的语法结构,来分析内存状况
作用:
调整环境到MRC
- 逻辑错误:访问未初始化的变量或者野指针等;
- 声明错误:从未使用过的对象;
- 内存管理错误:如内存泄漏等;(MRC&ARC)
缺点:
- 不一定准确,但是如果发现有提示,那么去结合上下文看一下,这里的代码是否有问题
场景演练(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修饰