2011-01-10 3 views
1

Étant donné un tableau clé/valeur de base, je veux stocker deux tableaux triés en fonction du tableau original: un tableau sera trié par nom, et l'autre par âge.Stockage de tableaux triés provoquant l'erreur EXC_BAD_ACCESS

Les tableaux semblent trier correctement lorsque je les affiche dans le journal; Toutefois, lorsque j'essaie d'y accéder ailleurs dans le code, une erreur EXC_BAD_ACCESS s'affiche.

Voici ce que j'ai jusqu'à présent:

// MyController.h 

@interface MyController : UIViewController { 
    NSMutableArray *originalArray; 
    NSMutableArray *nameArray; 
    NSMutableArray *ageArray; 
} 

@property (nonatomic, retain) NSMutableArray *originalArray; 
@property (nonatomic, retain) NSMutableArray *nameArray; 
@property (nonatomic, retain) NSMutableArray *ageArray; 

-(void)someRandomMethod; 

@end 


// MyController.m 

#import "MyController.h" 

@implementation MyController 

@synthesize originalArray; 
@synthesize nameArray; 
@synthesize ageArray; 

-(void)viewDidLoad { 

    // originalArray = (
    // { 
    //  "name" = "Sally"; 
    //  "age" = 18; 
    // }, 
    // { 
    //  "name" = "Chad"; 
    //  "age" = 26; 
    // }, 
    // { 
    //  "name" = "Carla"; 
    //  "age" = 24; 
    // }, 
    //) 

    // sort by name 
    NSSortDescriptor *sortByNameDescriptor; 
    sortByNameDescriptor = [[[NSSortDescriptor alloc]    
            initWithKey:@"name"                
            ascending:NO] autorelease]; 
    NSArray *sortByNameDescriptors = [NSArray arrayWithObject:sortByNameDescriptor]; 
    nameArray = [originalArray sortedArrayUsingDescriptors:sortByNameDescriptors]; 

    // sort by age 
    NSSortDescriptor *sortByAgeDescriptor; 
    sortByAgeDescriptor = [[[NSSortDescriptor alloc]    
            initWithKey:@"age"                
            ascending:NO] autorelease]; 
    NSArray *sortAgeDescriptors = [NSArray arrayWithObject:sortByAgeDescriptor]; 
    ageArray = [originalArray sortedArrayUsingDescriptors:sortByAgeDescriptors];  

    [super viewDidLoad]; 
} 

-(void)someRandomMethod { 
    // whenever I try to access the sorted arrays, I receive the EXC_BAD_ACCESS error 
    [[nameArray objectAtIndex:0] valueForKey:@"name"]; 
    [[ageArray objectAtIndex:0] valueForKey:@"age"]; 
} 

-(void)viewDidUnload { 
    self.originalArray = nil; 
    self.nameArray = nil; 
    self.ageArray = nil; 
    [super viewDidUnload]; 
} 

- (void)dealloc { 
    [originalArray release]; 
    [nameArray release]; 
    [ageArray release]; 
    [super dealloc]; 
} 

@end 

Toutes les idées?

MISE À JOUR: Merci à @robin, en changeant le code ci-dessus pour le code ci-dessous, tout fonctionne très bien:

// sort by name 
NSSortDescriptor *sortByNameDescriptor; 
sortByNameDescriptor = [[[NSSortDescriptor alloc]    
           initWithKey:@"name"                
           ascending:NO] autorelease]; 
NSArray *sortByNameDescriptors = [NSArray arrayWithObject:sortByNameDescriptor]; 
nameArray = [[NSMutableArray alloc] initWithArray:[originalArray sortedArrayUsingDescriptors:sortByNameDescriptors]]; 

// sort by age 
NSSortDescriptor *sortByAgeDescriptor; 
sortByAgeDescriptor = [[[NSSortDescriptor alloc]    
           initWithKey:@"age"                
           ascending:NO] autorelease]; 
NSArray *sortAgeDescriptors = [NSArray arrayWithObject:sortByAgeDescriptor]; 
ageArray = [[NSMutableArray alloc] initWithArray:[originalArray sortedArrayUsingDescriptors:sortByAgeDescriptors]];  

Répondre

2

Je ne pense pas que vous savez à ce sujet ou pas, mais à chaque fois que vous créez un objet comme chaîne ou un tableau ou un dictionnaire, avec des méthodes d'initialisation, puis le nombre se conserve augmente de 1

et si vous les créer comme ce

NSArray *anarray = [NSArray arrayWithArray:temp]; 

cela créera un autorelease objets qui seront libérés automatiquement après un certain temps.

Donc, mon conseil n'utilisez pas ce type de code si vous voulez utiliser les objets dans plus d'une fonction. Utilisez toujours d'abord les méthodes init pour faire le travail.

et si vous êtes sûr que les objets ne sont pas nécessaires pour le reste du programme que de les libérer en utilisant la méthode de libération.

+0

Wow ... vous avez tout à fait raison ... en ajoutant [[NSMutableArray alloc] initWithArray: ...] cela fonctionne parfaitement. Merci! –

+0

juste en général, pour ajouter à ce que robin a dit, autoreleasing n'est pas * toujours * la réponse. S'il vous plaît lire sur le sujet de retenir/libérer/autorelease. Ce n'est pas seulement que [NSArray arrayWithArray: temp] crée un objet autorelease, c'est que vous n'avez pas all/init, et que vous n'êtes donc pas responsable de sa libération. Ainsi, vous pouvez déduire que NSArray est. – jakev

+0

Depuis que j'alloue explicitement le nomArray et ageArray maintenant, je suis responsable de les libérer, et c'est pourquoi les choses fonctionnent, correct? –

Questions connexes