2010-07-18 51 views
0

我正在使用自定义类来显示表视图上的一些信息。 问题是,只要我滚动tableview内存泄漏...UITableView自定义类巨大泄漏

我想我的班上有什么问题。

请看看:

@interface Person : NSObject { 

NSString *name; 
NSString *surname; 
NSString *address; 
NSString *email; 

} 

@property (nonatomic, copy) NSString *name, *surname, *address, *email; 



@implementation Person 
@synthesize name, surname, address, email; 

-(id)init { 

[super init]; 
name = [[NSString alloc] init]; 
surname = [[NSString alloc] init]; 
address = [[NSString alloc] init]; 
email = [[NSString alloc] init]; 
return self; 
} 



- (void)dealloc 
{ 
[name release]; 
[surname release]; 
[address release]; 
[email release]; 
[super dealloc]; 
} 


#import "Person.h" 

@interface Group : NSObject { 

NSString *groupTitle; 
NSMutableArray *persons; 

} 

@property (readwrite, copy) NSString *groupTitle; 

- (void)addPerson:(Person *)person; 
- (void)removeAll; 
- (NSArray *)getPersons; 
- (int)PersonsCount; 

@end 




@implementation Group 
@synthesize groupTitle; 



-(id)init { 

[super init]; 
persons = [[NSMutableArray alloc] init]; 
return self; 
} 


-(void)addPerson:(Person *)person { 


[persons addObject:person]; 

} 

-(void)removeAll { 

[persons removeAllObjects]; 

} 

-(NSArray *) getPersons { 

return [persons copy]; 
[persons release]; 


} 

-(int)personsCount { 

return [persons count]; 

} 

-(void)dealloc { 

[groupTitle release], groupTitle = nil; 
[persons release], persons = nil; 
[super dealloc]; 
} 


@end 




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    ……. 


    Group *groupForRow = [[Group alloc] init]; 
    Person *personForRow = [[Person alloc] init]; 
    personForRow = [[groupForRow getPersons] objectAtIndex:indexPath.row]; 

    _personName = personForRow.name; 
    _personSurname = personForRow.surname; 
    _personAddress = personForRow.address; 
    _personEmail = personForRow.email; 


    [groupForRow release], groupForRow = nil; 
    [personForRow release], personForRow = nil; 

    ….. 

    return cell 
+0

的NSString是不可变的。不要在整个地方使用拷贝,并用'retain'而不是'copy'定义你的属性。 – 2010-07-18 09:55:29

+0

把'NSString'属性当作副本很好,但是'alloc'它们没用(你只是分配空字符串)。 – shosti 2010-07-18 10:37:46

回答

0

一些修改(阅读注释):

@interface Person : NSObject { 
    NSString *name; 
    NSString *surname; 
    NSString *address; 
    NSString *email; 
} 

// copy is OK for strings... 
@property (nonatomic, copy) NSString *name, *surname, *address, *email; 

@end 


@implementation Person 

@synthesize name, surname, address, email; 

- (id)init { 
    if (self = [super init]) { 
     // There is no need to allocate the strings 
     // In addition, once you write 'name = [[NSStrin alloc] init];' you don't use the property. 
     // If you do want to use the property setter then you should write 'self.name = @"some string";' 
    } 
    return self; 
} 


- (void)dealloc { 
    [name release]; 
    [surname release]; 
    [address release]; 
    [email release]; 
    [super dealloc]; 
} 

@end 


#import "Person.h" 

@interface Group : NSObject { 
    NSString *groupTitle; 
    NSMutableArray *persons; 
} 

// Any special reason for "readwrite" instead of "nonatomic"? 
@property (readwrite, copy) NSString *groupTitle; 
// This property is more important than the string: 
@property (nonatomic, retain) NSMutableArray *persons; 

- (void)addPerson:(Person *)person; 
- (void)removeAll; 
- (NSArray *)getPersons; 
- (int)PersonsCount; 

@end 


@implementation Group 

@synthesize groupTitle, persons; 

- (id)init { 
    if (self = [super init]) { 
     // Use the autoreleased array instance ([NSMutableArray array]) and set it to the property setter that will retain the object: 
     self.persons = [NSMutableArray array]; 
    } 
    return self; 
} 


- (void)addPerson:(Person *)person { 
    // I prefer using properties (the "self." in the beginning) instead of the members directly... 
    [self.persons addObject:person]; 
} 

- (void)removeAll { 
    [self.persons removeAllObjects]; 
} 

// I think that this getter is unnecessary - use the property instead... 
- (NSArray *) getPersons { 
    // There is no need to copy 
    return [persons copy]; 
    // Don't you have a warning for this line? It is never executed 
    [persons release]; 
} 

- (int)personsCount { 
    return [self.persons count]; 
} 

- (void)dealloc { 
    [groupTitle release], groupTitle = nil;// The "groupTitle = nil" is unnecessary. 
    [persons release], persons = nil;// The "persons = nil" is unnecessary. 
    [super dealloc]; 
} 

@end 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    ……. 


    Group *groupForRow = [[Group alloc] init];// Do you REALLY have to allocate this object each "cellForRowAtIndexPath"?? 
    Person *personForRow = [[Person alloc] init];// Get rid of the "= [[Person alloc] init]" - this is a leak (because of the next line) 
    personForRow = [[groupForRow getPersons] objectAtIndex:indexPath.row];// If you will use the property persons instead of the "getPersons" (that copies the array) then you will get rid of another leak 

    // What are these? 
    _personName = personForRow.name; 
    _personSurname = personForRow.surname; 
    _personAddress = personForRow.address; 
    _personEmail = personForRow.email; 

    // The " = nil" is unnecessary here... 
    [groupForRow release], groupForRow = nil;// If you won't allocate the group then you won't need this line... 
    [personForRow release], personForRow = nil;// NSZombie - you release object that you don't owe (do you have crashes, that you don't know why they are happen?) 

    ….. 

    return cell; 
} 
+0

非常感谢,大部分泄漏消失了,我学到了很多东西。再次感谢。 – Nimrod7 2010-07-19 08:32:55

0

有很多错在这里,请深入一点到目标-C,以获得使用@property@synthesize的把握来获得正常的getter/setter方法。

至于你的内存泄漏滚动时,它是由alloc S IN cellForRowAtIndexPath引起未通过任一个releaseautorelease平衡。

此:

Group *groupForRow = [[[Group alloc] init] autorelease]; 
Person *personForRow = [[[Person alloc] init] autorelease]; 

应解决大部分的泄漏。在SO浏览更多信息。

+0

均已发布groupForRow和personForRow。因此,使用autorelease和日志记录retainCount返回完全相同的数字。 – Nimrod7 2010-07-18 16:52:19

+0

我明白了。团体和个人内部会发生什么?例如。你能不能在内存爆炸的情况下循环?[[Group alloc] init] release]? – mvds 2010-07-18 17:29:44