【问题标题】:Detect memory leaks in Obj-C检测 Obj-C 中的内存泄漏
【发布时间】:2017-11-24 15:44:03
【问题描述】:

我有一段用 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");

所以当我在书中查找卡片时,它会在数组中返回该对象的引用,并且它的引用计数设置为 2,即使目标设置为 __weak ref;而从书中删除的对象,它删除的#after deleted# message 。 output

【问题讨论】:

  • 你尝试过使用静态分析器吗?
  • 不,我没试过

标签: ios objective-c memory-leaks automatic-ref-counting


【解决方案1】:

尝试在 Xcode 中使用 Memory Graph 调试器,它会准确显示导致此问题的对象引用。

【讨论】:

  • 我使用的是 XCode 7.0,所以对我来说有点问题
  • @VladyslavShepitko - Xcode 7 具有泄漏工具。在 Xcode 中使用 Product > Profile,然后选择 Leaks。
  • 是的,我知道,但它不会连接到控制台应用程序,使用简单的 iOS 应用程序它可以工作,也可以使用基于故事板,但控制台不能。
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2021-09-01
  • 2011-02-18
  • 2012-07-16
  • 2011-03-29
  • 2010-09-08
  • 2022-01-11
相关资源
最近更新 更多