Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MLeaksFinder添加成员变量内存泄漏检测 #82

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified MLeaksFinder/MLeakedObjectProxy.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/MLeakedObjectProxy.m
100644 → 100755
Empty file.
3 changes: 3 additions & 0 deletions MLeaksFinder/MLeaksFinder.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@
#elif COCOAPODS
#define _INTERNAL_MLF_RC_ENABLED COCOAPODS
#endif

//#define MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED //是否开启所有属性的检查

Empty file modified MLeaksFinder/MLeaksMessenger.h
100644 → 100755
Empty file.
15 changes: 15 additions & 0 deletions MLeaksFinder/NSArray+MemoryLeak.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// NSArray.h
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import <Foundation/Foundation.h>

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@interface NSArray(MemoryLeak)

@end
#endif
34 changes: 34 additions & 0 deletions MLeaksFinder/NSArray+MemoryLeak.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// NSArray.m
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import "NSArray+MemoryLeak.h"
#import "MLeaksFinder.h"

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@implementation NSArray(MemoryLeak)

- (void)willReleaseIvarList
{
if(!self.count)
{
return;
}

for(id ob in self)
{
[ob willReleaseIvarList];
}
}

- (BOOL)continueCheckObjecClass:(Class)objectClass
{
return YES;
}

@end
#endif
15 changes: 15 additions & 0 deletions MLeaksFinder/NSDictionary+MemoryLeak.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// NSDictionary.h
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import <Foundation/Foundation.h>

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@interface NSDictionary(MemoryLeak)

@end
#endif
34 changes: 34 additions & 0 deletions MLeaksFinder/NSDictionary+MemoryLeak.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// NSDictionary.m
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import "NSDictionary+MemoryLeak.h"
#import "MLeaksFinder.h"

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@implementation NSDictionary(MemoryLeak)

- (void)willReleaseIvarList
{
if(!self.count)
{
return;
}

for(id ob in self.allValues)
{
[ob willReleaseIvarList];
}
}

- (BOOL)continueCheckObjecClass:(Class)objectClass
{
return YES;
}

@end
#endif
5 changes: 5 additions & 0 deletions MLeaksFinder/NSObject+MemoryLeak.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@

+ (void)swizzleSEL:(SEL)originalSEL withSEL:(SEL)swizzledSEL;

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
- (void)willReleaseIvarList;
- (BOOL)continueCheckObjecClass:(Class)objectClass;
#endif

@end
104 changes: 104 additions & 0 deletions MLeaksFinder/NSObject+MemoryLeak.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
static const void *const kParentPtrsKey = &kParentPtrsKey;
const void *const kLatestSenderKey = &kLatestSenderKey;

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
static const void *const kCheckKey = &kCheckKey;
#endif

@implementation NSObject (MemoryLeak)

- (BOOL)willDealloc {
Expand Down Expand Up @@ -170,4 +174,104 @@ + (void)swizzleSEL:(SEL)originalSEL withSEL:(SEL)swizzledSEL {
#endif
}


#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
- (BOOL)leakChecked
{
NSNumber *leak = objc_getAssociatedObject(self, kCheckKey);
return [leak boolValue];
}

- (void)setLeakChecked:(BOOL)leakChecked
{
objc_setAssociatedObject(self, kCheckKey, @(leakChecked),OBJC_ASSOCIATION_RETAIN);
}

- (BOOL)continueCheckObjecClass:(Class)objectClass
{
if(!objectClass)
{
return NO;
}

NSBundle *bundle = [NSBundle bundleForClass:objectClass];
if(bundle != [NSBundle mainBundle])
{
return NO;
}

return YES;

}

- (void)willReleaseIvarLisWithTargetObjectClass:(id)targetObjectClass
{
if(!targetObjectClass)
{
return;
}
NSArray *viewStack = [self viewStack];
NSSet *parentPtrs = [self parentPtrs];

unsigned int outCount = 0;
Ivar * ivars = class_copyIvarList(targetObjectClass, &outCount);
NSString *stringType = nil;
for (unsigned int i = 0; i < outCount; i ++) {
Ivar ivar = ivars[i];
const char * name = ivar_getName(ivar);
const char * type = ivar_getTypeEncoding(ivar);
stringType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
//非NSObject类型不用继续遍历
if ((!name) || ![stringType hasPrefix:@"@"] || [stringType isEqualToString:@"@"]) {

continue;
}

id value = nil;

@try {
value = [self valueForKey:[NSString stringWithUTF8String:name]];
} @catch (NSException *exception) {
NSLog(@"class %@ valueForKey:%s throw NSException,",NSStringFromClass([targetObjectClass class]),name);
}

if(![value continueCheckObjecClass:[value class]])
{
continue;
}

NSString *className = NSStringFromClass([value class]);
[value setViewStack:[viewStack arrayByAddingObject:className]];
[value setParentPtrs:[parentPtrs setByAddingObject:@((uintptr_t)value)]];
[value willDealloc];
[value willReleaseIvarList];

}
free(ivars);
}

- (void)willReleaseIvarList
{
if([self leakChecked])
{
return;
}
[self setLeakChecked:YES];

if(![self continueCheckObjecClass:[self class]])
{
return;
}
[self willReleaseIvarLisWithTargetObjectClass:[self class]];

if(![self continueCheckObjecClass:[self superclass]])
{
return;
}
[self willReleaseIvarLisWithTargetObjectClass:[self superclass]];

}

#endif

@end
17 changes: 17 additions & 0 deletions MLeaksFinder/NSSet+MemoryLeak.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// NSSet.h
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import <Foundation/Foundation.h>

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@interface NSSet(MemoryLeak)

- (BOOL)continueCheckObjecClass:(Class)objectClass;

@end
#endif
36 changes: 36 additions & 0 deletions MLeaksFinder/NSSet+MemoryLeak.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// NSSet.m
// CTDebug
//
// Created by 王腾达 on 2017/11/6.
// Copyright © 2017年 liuweiso. All rights reserved.
//

#import "NSSet+MemoryLeak.h"
#import "MLeaksFinder.h"

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
@implementation NSSet(MemoryLeak)

- (void)willReleaseIvarList
{
if(!self.count)
{
return;
}

id obj;

NSEnumerator * enumerator = [self objectEnumerator];
while (obj = [enumerator nextObject]) {
[obj willReleaseIvarList];
}
}

- (BOOL)continueCheckObjecClass:(Class)objectClass
{
return YES;
}

@end
#endif
Empty file modified MLeaksFinder/UIApplication+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UIApplication+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UINavigationController+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UINavigationController+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UIPageViewController+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UIPageViewController+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UISplitViewController+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UISplitViewController+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UITabBarController+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UITabBarController+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UITouch+MemoryLeak.h
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UITouch+MemoryLeak.m
100644 → 100755
Empty file.
Empty file modified MLeaksFinder/UIView+MemoryLeak.h
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions MLeaksFinder/UIView+MemoryLeak.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ - (BOOL)willDealloc {
if (![super willDealloc]) {
return NO;
}

[self willReleaseChildren:self.subviews];

return YES;
}

Expand Down
Empty file modified MLeaksFinder/UIViewController+MemoryLeak.h
100644 → 100755
Empty file.
6 changes: 5 additions & 1 deletion MLeaksFinder/UIViewController+MemoryLeak.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,13 @@ - (BOOL)willDealloc {
[self willReleaseChild:self.view];
}

#ifdef MEMORY_LEAKS_ALL_OBJECT_FINDER_ENABLED
[self willReleaseIvarList];
#endif

return YES;
}

@end

#endif