44 votes

Traitement des problèmes de propriété de pointeur à pointeur dans ARC

Supposons que l'Objet A une propriété:

@property (nonatomic, strong) Foo * bar;

Synthétisé dans la mise en œuvre comme:

@synthesize bar = _bar;

L'objet B manipule un Foo **, comme dans cet exemple d'appel à partir de l'Objet A:

Foo * temp = self.bar;
[objB doSomething:&temp];
self.bar = temp;
  • Cela peut-il, ou quelque chose de similaire, être fait légitimement?
  • Qu'est-ce que la déclaration correcte pour l' doSomething: méthode?

En outre, supposons que l'Objet B peut être libéré avant que j'ai une chance de régler le bar de la propriété (et donc à prendre sur la propriété de l'instance pointée par temp) - Comment puis-je dire de l'ARC à la main d'un propriétaire de référence? En d'autres termes, si je voulais l'exemple suivant extrait de travailler, comment aurais-je besoin de la poignée de l'ARC des questions?

Foo * temp = self.bar;    // Give it a reference to some current value
[objB doSomething:&temp]; // Let it modify the reference
self.bar = nil;           // Basically release whatever we have
_bar = temp;              // Since we're getting back an owning reference, bypass setter
  • Que ne suis-je pas pensé?

MODIFIER

Basé sur @KevinBallard 's réponse, je veux juste confirmer ma compréhension. Est-ce correct?

Objet:

@implementation ObjectA

@synthesize bar = _bar;

- (void)someMethod
{
    ObjectB * objB = [[ObjectB alloc] initWithFoo:&_bar];
    // objB handed off somewhere and eventually it's "doSomething" method is called.
}

@end

L'Objet B:

@implementation ObjectB
{
    Foo * __autoreleasing * _temp;
}

- (id)initWithFoo:(Foo * __autoreleasing *)temp
{
    id self = [super init];
    if (self)
    {
        _temp = temp;
    }
    return self;
}

- (void)doSomething
{
    ...
    *_temp = [[Foo alloc] init]; 
    ...
}

@end

Cela crée une erreur de compilation: passing address of non-local object to __autoreleasing parameter for write-back

6voto

Kevin Ballard Points 88866

C'est parfaitement légitime. L'accès à la propriété n'est pas pertinent; en passant un pointeur vers un objet est généralement fait avec NSError* objets.

La bonne façon de déclarer votre méthode est

- (returntype)doSomething:(Foo * __autoreleasing *)arg;

Il déclare comme un pointeur vers un __autoreleasing de l'objet, ce qui signifie essentiellement que l'objet pointé est supposé avoir été -autoreleased.

Comme pour le "en Outre", ce n'est pas une question en vertu de l'ARC. Votre ligne

Foo * temp = self.bar;

est équivalent à

__strong Foo *temp = self.bar;

qui je l'espère est évident pour vous que cela rend temp une référence forte, et donc il est "propriétaire" de sa valeur tant que la variable existe. En d'autres termes, vous pouvez dire

Foo *temp = self.bar;
self.bar = nil;

et temp est toujours valide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X