43 votes

La Non-conservation de tableau pour les délégués

Dans une Cocoa Touch de projet, j'ai besoin d'une classe spécifique pour disposer non seulement d'un délégué unique objet, mais beaucoup d'entre eux.

Il semble que je devrais créer un NSArray pour ces délégués; le problème est que NSArray aurait tous ces délégués conserver, il ne devrait pas (par convention, les objets ne devraient pas conserver leurs délégués).

Dois-je écrire mon propre tableau de la classe pour éviter de soutènement ou il y a des méthodes plus simples? Merci!!!!

48voto

MarkPowell Points 11394

J'ai trouvé ce bout de code y a quelques temps (ne me souviens pas à qui l'attribuer).

Il est tout à fait ingenius, à l'aide d'une Catégorie pour permettre la création d'une mutable tableau qui n'a pas de conserver/diffusion de sauvegarde avec un CFArray avec les bons rappels.

@implementation NSMutableArray (WeakReferences)
    + (id)mutableArrayUsingWeakReferences {
    return [self mutableArrayUsingWeakReferencesWithCapacity:0];
    }

    + (id)mutableArrayUsingWeakReferencesWithCapacity:(NSUInteger)capacity {
    CFArrayCallBacks callbacks = {0, NULL, NULL, CFCopyDescription, CFEqual};
    // We create a weak reference array
    return (id)(CFArrayCreateMutable(0, capacity, &callbacks));
    }
@end

MODIFIER Trouvé l'article original: http://ofcodeandmen.poltras.com

26voto

Timo Points 560

Je suis présentant une limitation importante de l'une des premières réponses, avec une explication et une amélioration.

Johnmph a suggéré d'utiliser [NSValue valueWithNonretainedObject:].

Notez que lorsque vous faites cela, votre référence agit pas comme __weak, mais plutôt comme __unsafe_unretained , tandis que l'intérieur de la NSValue objet. Plus précisément, lorsque vous essayez d'obtenir votre référence arrière (à l'aide de [myNSValue nonretainedObjectValue]), votre application plante avec un EXC_BAD_ACCESS signal si l'objet a été libéré avant que le temps!

En d'autres termes, la faiblesse de référence n'est pas automatiquement mis à zéro à l'intérieur de l' NSValue objet. Ce qui m'a pris un tas d'heures pour comprendre. J'ai travaillé autour de ce par la création d'une classe simple avec seulement une faible ref de propriété.

Plus belle manière, en utilisant NSProxy, nous pouvons traiter l'objet wrapper entièrement, comme si c'est le contenu de l'objet lui-même!

// WeakRef.h
@interface WeakRef : NSProxy

@property (weak) id ref;
- (id)initWithObject:(id)object;

@end


// WeakRef.m
@implementation WeakRef

- (id)initWithObject:(id)object
{
    self.ref = object;
    return self;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
    invocation.target = self.ref;
    [invocation invoke];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
    return [self.ref methodSignatureForSelector:sel];
}

@end

17voto

Johnmph Points 2122

Vérifier la documentation de NSValue valueWithNonretainedObject méthode :

Cette méthode est utile pour empêcher un objet d'être conservée lorsqu'il est ajouté à une collection d'objets (comme une instance de NSArray ou NSDictionary).

13voto

leviathan Points 5207

Je vous suggère de ne pas-combattre-le-cadre et de l'utilisation NSPointerArray avec l' NSPointerFunctionsWeakMemory NSPointerFunctionOption comme ceci:

NSPointerArray *weakReferencingArray = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsWeakMemory];

// NSPointerFunctionsWeakMemory - Uses weak read and write barriers 
// appropriate for ARC or GC. Using NSPointerFunctionsWeakMemory 
// object references will turn to NULL on last release.

M'a bien servi dans les scénarios, où j'ai eu à concevoir un délégués de la matrice, ce qui auto-NULL références.

12voto

PeyloW Points 25312

Vous ne voulez pas faire cela! Cocoa Touch ont plusieurs concepts pour envoyer des événements, vous devez utiliser le bon concept pour chaque cas.

  1. Cible-action: Pour les contrôles d'INTERFACE utilisateur, tels que des boutons. Un expéditeur, zéro, un ou plusieurs récepteurs.
  2. Délégués: Pour un expéditeur et un destinataire uniquement.
  3. Notification: Pour un expéditeur, et de zéro ou plusieurs récepteurs.
  4. KVO: Plus fine que les notifications.

Ce que vous devez faire est d'examiner comment utiliser NSNotificationCenter classe. Ce est la bonne façon d'envoyer une notification qui ont plus d'un récepteur.

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