Wie kann ich dieses Problem beheben Klirren Warnung: „Objekts mit 0 retain zu Anrufern zählen zurück, wo +1 (Besitz) behalten Zahl erwartet wird“?

StackOverflow https://stackoverflow.com/questions/2837904

Frage

Ich habe ein Stück von Objective-C-Code, sieht wie folgt aus:

- (NSString *)copyData:(NSData *)data
{
    NSString *path = [[[self outputDirectory] stringByAppendingPathComponent:@"archive"] stringByAppendingPathExtension:@"zip"];
    NSLog(@"Copying data to %@", path);
    [data writeToFile:path atomically:NO];
    return path;
}

Der Code wird von einem initializer genannt, dass sieht wie folgt aus:

- (id)initWithData:(NSData *)data
{
    if ((self = [super init]) != nil) {
        NSString *path = [self copyData:data];        // Line 41 (referenced in warning, shown below)
        return [self initWithContentsOfFile:path];
    }
    return self;
}

Wenn das Klirren statische Analysator ausgeführt wird, habe ich die folgenden Warnungen für die path Variable erhalten:

  

Mögliches Leck eines Objekt zugeordnet auf der Leitung 41 und gespeichert in ‚Pfad‘

     

Objekt mit 0 zählt behalten zu Aufrufer zurückgegeben, wo +1 (Besitz) Zahl beibehalten wird erwartet,

Ich bin verwirrt. Mein Verständnis ist, dass stringByAppendingPathComponent sollte eine Autoreleased String zurück, so dass es sollte eine Nettozahl von 0 beibehalten hat (Offensichtlich ich nicht will es zu behalten.)

Ich habe zu verändern copyData: folgenden versucht zurückzukehren, aber es hat nicht der Warnung loswerden

return [[path retain] autorelease];

Also, was ist der Deal mit dieser Warnung?

War es hilfreich?

Lösung

Ich vermute, es ist nur eine Methode mit dem Präfix copy zu bemerken und das Markieren, dass als etwas, das etwas zurückgeben sollte, dass der Anrufer besitzt, weil er denkt, dass es folgendes Cocoa Namenskonventionen.

In Ihrem Fall natürlich, Sie beziehen sich auf Dateien und so weiter, so dass es eine vernachlässigbares Warnung ist. Wenn Sie den Namen Ihrer Methode ändern, um so etwas wie saveData: statt, ich wette, wird die Warnung weg.

Andere Tipps

Auch für Zeiten, in denen Sie wirklich wollen, ein Verfahren nennen mit ‚Kopie‘ oder etwas, weil unabhängig von Cocoa Speichermanagement-Richtlinien, zu kopieren ist der beste Name für die Methode, können Sie die Methode declairation mit NS_RETURNS_NOT_RETAINED mit Anmerkungen versehen und dann Clang werden Sie keine Warnung geben. Also:

// Copies data from data to string; does not follow the copy rule
- (NSString*)copyData:(NSData*)data NS_RETURNS_NOT_RETAINED;

Da die Methode der Namen copy in ihm hat, ist der Analysator das zurückgegebene Objekt erwartet hat eine +1 Zahl beibehalten, nach der Speicherverwaltung .

Nein, das ist falsch; es sei denn, die Methode „alloc“, „Kopieren“, „neu“, oder eines der anderen Schlüsselwörter enthält, die das Objekt durch den Aufrufer im Besitz wird schon sagt, gibt die Methode eine Autoreleased oder anderweitig Objekt verwaltet, so stringByAppendingPathComponent eine Autoreleased String zurückgibt .

Hinzu kommt, dass, Ihre Methode „copydata“, enthält das Wort „Kopie“, was bedeutet, dass das Ergebnis im Besitz sein sollte (und freigegeben) vom Anrufer. Allerdings hat das Ergebnis, das Sie zurückgegeben worden Autoreleased, damit die Fehlermeldung, dass es Sie gibt. Wenn Sie den Fehler beheben möchten, dann Autorelease nicht. Das heißt:

 return [path retain]

Natürlich, dass die Anrufer Ihrer Funktion Notwendigkeit impliziert, dass es zu lösen. Alternativ dazu können Sie den Namen Ihrer Funktion ändern, so dass es mit den Richtlinien der Speicherverwaltung entspricht.

Der Name "copydata", IMHO, ist nicht intuitiv sowieso. Ich würde vorschlagen, dass Sie Ihre Funktion auf „pathToSavedDataWithData“ umbenennen oder dergleichen. Etwas, das sagt, was es tatsächlich tut.

Ich werde einen Stich an diese nehmen und denken, dass Sie genau die gleiche Fehlermeldung erhalten würden, auch nicht den Namen Ihrer Routine mit started „Kopie ...“ ist oder nicht. Ich habe gerade in einem ähnlichen Szenario endete und „kopieren“ war nicht Teil des Namens der Routine, die ich rief. Clang gab die Fehlermeldung, nur weil ich ein Autoreleased Objekt zurückkehrte, eine gefährliche Situation. Dadurch könnte die

  return [path retain]  

Trick am Ende, wie empfohlen von Michael kümmerte sich um das Problem.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top