2010-07-18 101 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