Andrea "Kiraya"Magini

IT Professional Master

Single post

Creare Classi Statiche e Singleton in Objective C

Per creare una classe che sia raggiungibile da ogni parte del nostro codice, abbiamo due alternative: realizzare una classe statica con metodi e attributi statici, oppure implementare il pattern del Singleton.
Preferisco generalmente la seconda scelta più orientata ad un design pulito del nostro codice e rimanendo legato alla programmazione ad oggetti.
Per creare una classe statica, con attributi e metodi statici definiamo l’interfaccia:
[cce lang=”objc”]
@interface MyStaticClass : NSObject
+ (int)getIntMethod;
+ (void)setIntMethod:(int)value;
@end
[/cce]
e poi implementiamola:
[cce lang=”objc”]
#import “MyStaticClass.h”
@implementation MyStaticClass
static int staticValue = 1;
+ (int)getIntMethod {
return staticValue;
}
+ (void)setIntMethod:(int)value {
staticValue = value;
}
+ (id)alloc {
[NSException raise:@”Non può essere istanziata format:@”Static class ‘ClassName’ non può essere instanziato”];
return nil;
}
@end
[/cce]
importante l’override dell’alloc per non permettere alla classe di essere istanziata.
Per un approccio più elegante e sicuramente più riusabile, implementiamo invece il Design Pattern del Singleton:
[cce lang=”objc”]
@interface MySingleton : NSObject
{
}
-(int)getIntMethod;
-(void)setIntMethod:(int)value;
+ (MySingleton *) m_MySingleton;
@end
[/cce]
Implementiamo la nostra interfaccia:
[cce lang=”objc”]
#import “MySingleton.h”
@implementation MySingleton
static MySingleton *m_MySingleton =nil;
static int staticValue = 1;
+ (MySingleton *) m_MySingleton
{
if (m_MySingleton == nil)
{
//creo l’istanza
m_MySingleton = [[super allocWithZone:NULL] init];
}
return m_MySingleton;
}
– (int)getIntMethod {
return staticValue;
}
– (void)setIntMethod:(int)value {
staticValue = value;
}
+ (id)allocWithZone:(NSZone *)zone
{
//sincronizzo in modo da rendere la fase di allocazione ThreadSafe
//in modo da gestire più thread che richiedono contemporaneamente il Singleton
@synchronized(self)
{
if (m_MySingleton == nil)
{
m_MySingleton = [super allocWithZone:zone];
return m_MySingleton;
}
}
return nil;
}
– (id)copyWithZone:(NSZone *)zone
{
//non e’ possibile clonarlo e quindi ritorna sempre la stessa istanza.
return self;
}
– (id)retain
{
return self;
}
– (NSUInteger)retainCount
{
//in questo modo il suo refCount non scenderà mai a zero.
return NSUIntegerMax;
}
– (void) release
{
//non fa nulla.
}
– (id)autorelease
{
return self;
}
@end
[/cce]
Piccola correzione. I metodi nel singleton ovviamente non devono essere statici (tranne il metodo che permette l’accesso all’istanza).