2011-09-15 1 views
2

J'écris une application multithread pour iPhone, et j'utilise NSLock's pour m'assurer que certaines opérations (comme charger des sons à partir d'un fichier) se comporteront comme des atomes. Pour simplifier l'acquisition de verrous à partir de différentes parties de mon application, j'ai écrit la classe suivante, qui me permet de verrouiller et de débloquer des verrous simplement en passant NSString avec le nom. Si un tel verrou n'existe pas, il le crée et l'enregistre pour l'avenir. Je l'ai testé et il semble fonctionner correctement (car il donne juste accès aux objets NSLock et ne modifie pas leur comportement).NSLock "controller" class

Ma question est la suivante: est-il acceptable d'avoir et d'utiliser une telle classe, ou ai-je un malentendu dans le concept de serrures?

Locker.h 

#import <Foundation/Foundation.h> 

@interface Locker : NSObject { } 

+ (void) purgeLocks; 
+ (NSLock*) lockWithName: (NSString*) name; 
+ (void) lock: (NSString*) name; 
+ (void) unlock: (NSString*) name; 
+ (BOOL) tryLock: (NSString*) name; 

@end 



Locker.m 

#import "Locker.h" 

static NSMutableDictionary* locks = nil; 

@implementation Locker 

+ (void) initialize { 
    locks = [[NSMutableDictionary dictionary] retain]; 
} 

+ (void) purgeLocks { 
    [locks release]; 
    [Locker initialize]; 
} 

+ (NSLock*) lockWithName: (NSString*) name { 
    NSLock* lock = nil; 
    @synchronized([Locker class]) { 
     lock = [locks objectForKey: name]; 
     if(!lock) { 
      lock = [[[NSLock alloc] init] autorelease]; 
      [lock setName: name]; 
      [locks setObject: lock forKey: name]; 
     } 
    } 
    return lock; 
} 

+ (void) lock: (NSString*) name { 
    [[Locker lockWithName: name] lock]; 
} 

+ (void) unlock: (NSString*) name { 
    [[Locker lockWithName: name] unlock]; 
} 

+ (BOOL) tryLock: (NSString*) name { 
    return [[Locker lockWithName: name] tryLock]; 
} 

@end 

Répondre

0

Cela me semble assez lourd. Êtes-vous sûr de ne pas pouvoir simplifier la conception? (GCD vient à l'esprit.) Presque chaque application iOS est multithread, et à mon humble avis, il est rare de voir de tels assistants de verrouillage que vous avez écrit. S'il y a un endroit où le KISS principle brille, je suis sûr que c'est multithreading.

+0

Merci, je vais regarder dans GCD. Ci-dessus est juste ce qui m'est venu à l'esprit en premier. Le problème principal auquel je suis confronté est lorsque l'utilisateur appuie sur le bouton play, je commence à charger le son du fichier dans un autre thread, mais si l'utilisateur appuie rapidement sur le bouton stop, ce message devient inutile, car le son est toujours chargé. Quand, finalement, il charge, il commence à jouer, et ce n'est déjà pas nécessaire. J'ai essayé de démarrer toutes les méthodes liées dans le même fil, mais j'ai rencontré quelques problèmes. KISS est génial, seulement parfois il est difficile de savoir, est ce que vous faites simple ou pas :) Pour une raison quelconque, ce code me semble simple. – Least

+0

Je ne connais pas les détails, mais les files d'attente d'envoi sonnent comme un bon match pour ce que vous décrivez. (Vous enverriez juste tous les messages de contrôle sur une file d'attente sérielle, ce qui vous assurerait que l'événement stop n'arrivera pas avant le chargement de l'audio.) Pour moi, les signes révélateurs de l'abandon du principe KISS seraient les méthodes de classe Objets "manager" et plusieurs verrous. YMMV. – zoul

1

@synchronized is slow, évitez-le. Attribuez un verrou au + initialize et utilisez-le à la place. Mais j'irais pour un singleton au lieu d'utiliser des méthodes de classe, mais c'est plus ou moins une question de goût.

L'inconvénient majeur de votre approche est que vous devez verrouiller un verrou pour obtenir un autre verrou. Dans une application fortement multi-threadée, ce méta-verrou (votre @synchronized actuel) peut devenir un goulot d'étranglement des performances même si les threads veulent tous accéder à des verrous différents.

Questions connexes