Στόχος-C: Καθορισμός της διαχείρισης μνήμης σε μια μέθοδο

ψήφοι
5

Είμαι σχεδόν εκεί κατανόηση απλή διαχείριση καταμέτρηση αναφορά / μνήμης σε Objective-C, όμως είμαι έχοντας μια δύσκολη στιγμή με τον κωδικό. Είμαι απελευθερώνοντας mutableDict (σχολίασε στην παρακάτω κώδικα) και αυτό είναι που προκαλεί επιζήμια συμπεριφορά κωδικό μου. Αν Άφησα τη διαρροή μνήμης, λειτουργεί όπως αναμένεται, αλλά αυτό δεν είναι προφανώς η απάντηση εδώ. ;-) Θα κάποιος από εσάς τους πιο έμπειρους λαοί την καλοσύνη να μου προς τη σωστή κατεύθυνση και πώς μπορώ να ξαναγράψουν κάποια από αυτή τη μέθοδο για να χειριστεί καλύτερα το αποτύπωμα της μνήμης μου; Κυρίως με το πώς είμαι διαχείρισης NSMutableDictionary * mutableDict, καθώς αυτό είναι το μεγάλο ένοχος εδώ. Θα ήθελα να κατανοήσουν το πρόβλημα, και όχι μόνο copy / paste κώδικα - έτσι κάποια σχόλια / ανατροφοδότηση είναι ιδανική. Σας ευχαριστώ όλους.

- (NSArray *)createArrayWithDictionaries:(NSString *)xmlDocument 
                               withXPath:(NSString *)XPathStr {

    NSError *theError = nil;
    NSMutableArray *mutableArray = [[[NSMutableArray alloc] init] autorelease];
    //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
    CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError] retain]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];
    int i, j, cnt = [nodes count];
    for(i=0; i < cnt; i++) {
        CXMLElement *xmlElement = [nodes objectAtIndex:i];
        if(nil != xmlElement) {
            NSArray *attributes = [NSArray array];
            attributes = [xmlElement attributes];
            int attrCnt = [attributes count];
            NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
            for(j = 0; j < attrCnt; j++) {
                if([[[attributes objectAtIndex:j] name] isKindOfClass:[NSString class]]) 
                    [mutableDict setValue:[[attributes objectAtIndex:j] stringValue] forKey:[[attributes objectAtIndex:j] name]];
                else 
                    continue;
            }
            if(nil != mutableDict) {
                [mutableArray addObject:mutableDict];
            }
            [mutableDict release];  // This is causing bad things to happen.
        }
    }

    return (NSArray *)mutableArray;
}
Δημοσιεύθηκε 26/02/2009 στις 23:32
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
5

Εδώ είναι ισοδύναμο επανεγγραφή του κώδικα σας:

- (NSArray *)attributeDictionaries:(NSString *)xmlDocument withXPath:(NSString *)XPathStr {
    NSError *theError = nil;
    NSMutableArray *dictionaries = [NSMutableArray array];
    CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:xmlDocument options:0 error:&theError]; 
    NSArray *nodes = [theXMLDocument nodesForXPath:XPathStr error:&theError];

    for (CXMLElement *xmlElement in nodes) {
        NSArray *attributes = [xmlElement attributes];
        NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary];
        for (CXMLNode *attribute in attributes) {
            [attributeDictionary setObject:[attribute stringValue] forKey:[attribute name]];
        }

        [dictionaries addObject:attributeDictionary];
    }

    [theXMLDocument release];
    return attributeDictionaries;
}

Ανακοίνωση έκανα μόνη αναφορά καταμέτρηση σε theXMLDocument. Αυτό συμβαίνει γιατί οι πίνακες και τα λεξικά ζουν πέρα από το πεδίο εφαρμογής αυτής της μεθόδου. Η arrayκαι dictionaryμέθοδοι κατηγορία δημιουργήσει autoreleased περιπτώσεις NSArrayκαι NSMutableDictionaryαντικειμένων. Εάν ο καλών δεν τους διατηρεί ρητά, θα κυκλοφορήσει αυτόματα στην επόμενη πράσινο γύρο του βρόχου εκδήλωση της εφαρμογής.

  • Αφαίρεσα επίσης κώδικα που ποτέ δεν πρόκειται να εκτελεστεί. Η CXMLNode nameμέθοδος λέει ότι επιστρέφει ένα string, έτσι ώστε τεστ θα είναι πάντα αλήθεια.
  • Αν mutableDictείναι nil, έχετε μεγαλύτερα προβλήματα. Είναι καλύτερα να ρίχνει μια εξαίρεση από σιωπηλά αποτύχει, έτσι έκανα μακριά με αυτό το τεστ, πάρα πολύ.
  • Θα χρησιμοποιηθεί επίσης το σχετικά νέο forσύνταξη καταμέτρηση, η οποία καταργεί μετρητή μεταβλητές σας.
  • Θα μετονομαστεί σε κάποιες μεταβλητές και η μέθοδος να είναι λίγο πιο κακάο-ish. Κακάο είναι διαφορετική από τις περισσότερες γλώσσες από το γεγονός ότι είναι γενικά θεωρείται σωστό να χρησιμοποιήσει ένα ρήμα όπως το «δημιουργήσει», εκτός αν ρητά θέλουν να κάνουν ο καλών υπεύθυνος για την αποδέσμευση ό, τι αντικείμενο θα επιστρέψει.
  • Εσείς δεν κάνετε τίποτα με theError. Θα πρέπει είτε να ελέγξει και να αναφέρετε το σφάλμα, ή αλλιώς να περάσει το nilαν δεν πρόκειται να το ελέγξουμε. Δεν υπάρχει νόημα στο να καταστεί η εφαρμογή χτίσει ένα αντικείμενο λάθος δεν πρόκειται να χρησιμοποιήσετε.

Ελπίζω ότι αυτό βοηθά να σας πάρει τόνισε προς τη σωστή κατεύθυνση.

Απαντήθηκε 27/02/2009 στις 00:18
πηγή χρήστη

ψήφοι
1

Λοιπόν, απελευθερώνοντας mutableDict πραγματικά δεν πρέπει να προκαλούν κανένα πρόβλημα, διότι η γραμμή πάνω από αυτό (προσθήκη mutableDict να mutableArray) θα διατηρήσει αυτόματα. Αν και δεν είμαι σίγουρος τι ακριβώς δεν πάει καλά με τον κωδικό σας (δεν διευκρίνισε τι «κακά πράγματα» σημαίνει), υπάρχουν μερικά γενικά πράγματα θα ήθελα να προτείνω:

  1. Μην αυτόματης κυκλοφορίας mutableArray αμέσως. Ας είναι μια τακτική δήλωση αΐΐοο / init και αυτόματης κυκλοφορίας όταν μπορείτε να το επιστρέψετε ( «επιστροφή [mutableArray αυτόματης κυκλοφορίας]?»).

  2. theXMLDocument υπάρχει διαρροή, να είστε βέβαιος να απελευθερώσει ότι πριν από την επιστροφή. Επίσης, δεν χρειάζεται να το διατηρήσει σαν να είναι. αΐΐοο / init κάνει τη δουλειά του, ξεκινώντας το αντικείμενο διατηρεί καταμέτρηση σε 1, διατηρώντας και πάλι μόνο εξασφαλίζει διαρροές για πάντα. Απαλλαγείτε από το διατηρήσει και αφήστε το, πριν επιστρέψει και δεν θα διαρρεύσει.

  3. Απλά μια συμβουλή: να είστε σίγουροι ότι θα διατηρήσει την τιμή επιστροφής αυτής της μεθόδου, όταν το χρησιμοποιείτε αλλού - το αποτέλεσμα έχει autoreleased καθώς δεν είναι εγγυημένη για να είναι γύρω, όταν το χρειάζεστε, εκτός και αν διατηρούν ρητά / αφήστε το κάπου.

Σε αντίθετη περίπτωση, ο κωδικός αυτός θα πρέπει να λειτουργήσει. Αν και πάλι δεν το κάνει, ένα άλλο πράγμα που θα προσπαθήσουμε είναι ίσως κάνει [mutableArray addObject: [mutableDict αντιγράψετε]] για να εξασφαλίσει ότι mutableDict σας προκαλεί κανένα πρόβλημα, όταν αυτή εκδοθεί.

Απαντήθηκε 26/02/2009 στις 23:49
πηγή χρήστη

ψήφοι
0

Στη Διαχείριση Μνήμης Οδηγός προγραμματισμού με θέμα Επιστρέφοντας Αντικείμενα από Μεθόδων (μετακινηθείτε προς τα κάτω), υπάρχουν μερικά απλά παραδείγματα για το πώς να επιστρέψουν τα αντικείμενα από μια μέθοδο με την σωστή διαχείριση της μνήμης.

Απαντήθηκε 08/09/2010 στις 22:48
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more