iOS开发-常见内存泄漏
2021-07-15 本文已影响0人
来者可追文过饰非
最近使用Leaks工具对项目进行了一波内存泄漏的检测,发现的问题及解决方式总结如下
- 使用class_copyPropertyList 或者 class_copyPropertyList 之后没有释放
unsigned int outCount;
Ivar *ivars = class_copyIvarList([self class], &outCount);
...
...
// 释放 防止内存泄漏
free(ivars);
2.以下代码会检测到内存泄漏
+ (id)load:(NSString *)service
{
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Configure the search setting
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
[keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
} @finally {
}
}
return ret;
}
修改方式 (释放掉被SecItemCopyMatching引用的CFDictionaryRef)
+ (id)load:(NSString *)service
{
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Configure the search setting
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
[keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
CFDataRef keyData = NULL;
CFDictionaryRef cf_query = (__bridge_retained CFDictionaryRef)keychainQuery;
if (SecItemCopyMatching(cf_query, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
} @finally {
}
}
CFRelease(cf_query);
return ret;
}
3.GoogleDataTransport 中内存泄漏,源代码如下
image.png
该问题在8.3.1中已经解决,遇到此问题的可以更新下GoogleDataTransport SDK至最新版本试一下
image.png