Question

Je suis en train d'écrire un cadre et j'ai un objet avec une méthode d'initialisation personnalisée:

@implementation OSDatabase
@synthesize database;

// MEM
- (void)dealloc {
  sqlite3_close(database);

  [super dealloc];
}

// INIT
- (id)initWithDatabasePath:(NSString *)path error:(NSError **)error {
  if (self = [super init]) {
    if (!sqlite3_open_v2([path UTF8String], &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
      error = [NSError errorWithDomain:@"OSDatabaseErrorDomain" code:1 userInfo:nil];
      [self dealloc];
      return nil;
    }
  }

  return self;
}

@end

Est-il sûr d'appeler dealloc à l'intérieur d'une méthode de init si une erreur occoured? Je ne suis pas sûr à ce sujet et la gestion de la mémoire est l'une des choses les plus importantes dans ma vie.

Merci.

Était-ce utile?

La solution

  

Est-il sûr d'appeler dealloc à l'intérieur d'une méthode d'initialisation si une erreur occoured?

Non

. Envoyer -release comme vous le feriez partout ailleurs. Même dans -init vous ne pouvez pas garantir que le nombre actuel est conserviez 1.


Pourquoi vous devez envoyer jamais -dealloc sauf dans [super dealloc] -dealloc? La raison est que vous ne pouvez pas garantir que jamais quelque chose d'autre a aussi une référence à votre objet, même dans le -init de votre objet, car le [super init] peut choisir de conserver l'objet.

Si l'objet retourné par [super init] a retain compte de 1, l'envoi -release aura le même effet que l'envoi -dealloc. Si elle a un retain compte de plus de 1, quelque chose d'autre pense qu'il est propriétaire de l'objet et deallocing il partirait avec un pointeur invalide, -release est toujours la bonne chose à faire.

En outre, ceci:

while([self retainCount] != 0){[self release];}

entraînerait une boucle infinie et est une idée terrible pour un certain nombre de raisons. Retain compte d'objets ne vont jamais à 0. -release ressemble à quelque chose comme ceci:

- (id)release
{
    if (retainCount == 1)
    {
        [self dealloc];
    }
    else
    {
        retainCount--;
    }
}

de sorte que la boucle décrémenter le conserver à compter 1, puis appeler sans cesse dealloc toujours ou jusqu'à ce que la corruption du tas, il a causé conduit à un défaut de seg.

En plus de ne jamais atteindre zéro, Retain peut être UINT_MAX (par exemple dans littéraux chaîne ou numérique) qui signifie familièrement « cet objet ne doit jamais être désalloué ». Si le nombre est de conserver UINT_MAX, -release ne décrémenter.

Autres conseils

Par docs vous ne devriez jamais appeler directement dealloc - méthode seulement [super dealloc] dans votre dealloc personnalisé.

Je pense appeler release devrait faire au lieu que prévu (au moins si vous utilisez la méthode d'initialisation uniquement en configuration standard alloc-init).

Comme Vladimir dit que vous ne devriez jamais appeler directement dealloc. lorsque le nombre de conserver un objet atteint 0, Cocoa appelle automatiquement dealloc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top