检测 Obj-C 中的内存泄漏
Detect memory leaks in Obj-C
我有一段代码是用Objective-C写的,当我运行它的时候,它会导致内存泄漏。我找不到它出现在哪里。
@interface AddressCard : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *email;
-(void) print;
-(id)initWithName:(NSString*)name email: (NSString*)_email;
-(NSComparisonResult) compareNames:(id)element;
@end
@implementation AddressCard
@synthesize name = _name, email = _email;
-(id)initWithName:(NSString*)name email: (NSString*)mail{
if (self = [super init]){
self.name = name;
self.email = mail;
}
return (self);
}
-(BOOL) isEqual:(AddressCard*)other {
if ([self.name isEqualToString:other.name] == YES &&
[self.email isEqualToString:other.email] == YES) {
return (YES);
}
return (NO);
}
-(NSComparisonResult) compareNames:(id)element{
return [self.name compare:[element name]];
}
-(void) dealloc {
NSLog(@"Delete card %@ %@", [self name], [self email]);
}
@end
@interface AddressBook : NSObject{
NSString *name;
NSMutableArray *cards;
}
-(id) initWithName:(NSString*)newName;
-(void) addCard:(AddressCard*) newCard;
-(void) removeCard:(AddressCard*)cardToDelete;
-(AddressCard*)lookUp:(NSString*) searchName;
-(void) test;
@end
@implementation AddressBook
-(id) initWithName:(NSString*)newName{
if (self = [super init]) {
name = [NSString stringWithString:newName];
cards = [[NSMutableArray alloc]init];
}
return (self);
}
-(void) addCard:(AddressCard*) newCard{
[cards addObject:newCard];
}
-(AddressCard*)lookUp:(NSString*) searchName {
for (AddressCard *card in cards) {
if ([[card name] caseInsensitiveCompare:searchName] == NSOrderedSame) {
return card;
}
}
return (nil);
}
-(void) removeCard:(AddressCard*)cardToDelete{
[cards removeObjectIdenticalTo:cardToDelete];
}
-(void) sort{
[cards sortUsingSelector:@selector(compareNames:)];
}
-(void)dealloc {
NSLog(@"deleting addressBook");
//cards = nil;
}
-(void) test{
for (AddressCard *card in cards) {
NSLog(@"ref count %ld for %@", CFGetRetainCount((__bridge CFTypeRef)card), [card name]);
}
}
@end
测试代码:
AddressBook *book = [[AddressBook alloc]initWithName:@"my book"];
[book addCard: [[AddressCard alloc] initWithName:@"Chandler Rids" email:@"Chandler.R@gmail.com"]];
[book addCard: [[AddressCard alloc] initWithName:@"Bob Dilan" email:@"bob.dilan@gmail.com"]];
[book addCard: [[AddressCard alloc] initWithName:@"Frank Daragon" email:@"frank.daragon@gmail.com"]];
NSLog(@"counting ref for items _1: ");
[book test];
__weak AddressCard *forDeleteCard = [book lookUp:@"Frank Daragon"];
NSLog(@"Removing from addres book:");
[book removeCard:forDeleteCard];
NSLog(@"testing:");
[book test];
NSLog(@"---- count %ld for %@", CFGetRetainCount((__bridge CFTypeRef)forDeleteCard), [forDeleteCard name]);
forDeleteCard = nil;
book = nil;
NSLog(@"after deleting");
所以当我在书中查找卡片时,它 return 数组中该对象的引用,并且它的引用计数设置为 2,即使目标设置为 __weak 引用;而从书中删除的对象,它删除了#after deleting# 消息。
output
尝试在 Xcode 中使用 Memory Graph 调试器,它会准确显示是什么对象引用导致了这个问题。
我有一段代码是用Objective-C写的,当我运行它的时候,它会导致内存泄漏。我找不到它出现在哪里。
@interface AddressCard : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *email;
-(void) print;
-(id)initWithName:(NSString*)name email: (NSString*)_email;
-(NSComparisonResult) compareNames:(id)element;
@end
@implementation AddressCard
@synthesize name = _name, email = _email;
-(id)initWithName:(NSString*)name email: (NSString*)mail{
if (self = [super init]){
self.name = name;
self.email = mail;
}
return (self);
}
-(BOOL) isEqual:(AddressCard*)other {
if ([self.name isEqualToString:other.name] == YES &&
[self.email isEqualToString:other.email] == YES) {
return (YES);
}
return (NO);
}
-(NSComparisonResult) compareNames:(id)element{
return [self.name compare:[element name]];
}
-(void) dealloc {
NSLog(@"Delete card %@ %@", [self name], [self email]);
}
@end
@interface AddressBook : NSObject{
NSString *name;
NSMutableArray *cards;
}
-(id) initWithName:(NSString*)newName;
-(void) addCard:(AddressCard*) newCard;
-(void) removeCard:(AddressCard*)cardToDelete;
-(AddressCard*)lookUp:(NSString*) searchName;
-(void) test;
@end
@implementation AddressBook
-(id) initWithName:(NSString*)newName{
if (self = [super init]) {
name = [NSString stringWithString:newName];
cards = [[NSMutableArray alloc]init];
}
return (self);
}
-(void) addCard:(AddressCard*) newCard{
[cards addObject:newCard];
}
-(AddressCard*)lookUp:(NSString*) searchName {
for (AddressCard *card in cards) {
if ([[card name] caseInsensitiveCompare:searchName] == NSOrderedSame) {
return card;
}
}
return (nil);
}
-(void) removeCard:(AddressCard*)cardToDelete{
[cards removeObjectIdenticalTo:cardToDelete];
}
-(void) sort{
[cards sortUsingSelector:@selector(compareNames:)];
}
-(void)dealloc {
NSLog(@"deleting addressBook");
//cards = nil;
}
-(void) test{
for (AddressCard *card in cards) {
NSLog(@"ref count %ld for %@", CFGetRetainCount((__bridge CFTypeRef)card), [card name]);
}
}
@end
测试代码:
AddressBook *book = [[AddressBook alloc]initWithName:@"my book"];
[book addCard: [[AddressCard alloc] initWithName:@"Chandler Rids" email:@"Chandler.R@gmail.com"]];
[book addCard: [[AddressCard alloc] initWithName:@"Bob Dilan" email:@"bob.dilan@gmail.com"]];
[book addCard: [[AddressCard alloc] initWithName:@"Frank Daragon" email:@"frank.daragon@gmail.com"]];
NSLog(@"counting ref for items _1: ");
[book test];
__weak AddressCard *forDeleteCard = [book lookUp:@"Frank Daragon"];
NSLog(@"Removing from addres book:");
[book removeCard:forDeleteCard];
NSLog(@"testing:");
[book test];
NSLog(@"---- count %ld for %@", CFGetRetainCount((__bridge CFTypeRef)forDeleteCard), [forDeleteCard name]);
forDeleteCard = nil;
book = nil;
NSLog(@"after deleting");
所以当我在书中查找卡片时,它 return 数组中该对象的引用,并且它的引用计数设置为 2,即使目标设置为 __weak 引用;而从书中删除的对象,它删除了#after deleting# 消息。 output
尝试在 Xcode 中使用 Memory Graph 调试器,它会准确显示是什么对象引用导致了这个问题。