Articoli con Tag ‘classe’


La regola dell’AND logico nei CSS

Una caratteristica dei fogli di stile che pochi conoscono e usano è quella di poter definire la regola della “concorrenza” di classi! Un tag, infatti, può possedere una o più classi associate, cosa che rende quest’ultime estremamente versatili, oltre che le mie preferite. Come molti sviluppatori usano fare, anch’io tendo ad associare agli ID poche regole CSS, se non nessuna. L’ideale, a rigor di logica, sarebbe inserire gli ID solo per scopi di scripting, perché identificano in modo univoco un elemento all’interno del DOM.

Continua...

Objective-C: notifiche e delegati

In Objective-C abbiamo due modi molto utilizzati per ricevere ed inviare messaggi tra classi: le notifiche e i delegati. La differenza tra i due, oltre che essere a livello di implementazione, dipende sostanzialmente da “quanti” – oggetti – possono ricevere un messaggio. Prima di tutto lasciatemi mostrare come nasce il concetto di delegato.

Continua...

Objective-C: public, protected e private

Scrissi un articolo simile per ActionScript tempo fa: Actionscript 3.0: public, protected, private e internal. Rileggendolo mi sono accorto di due cose: la prima è stata l’estrema somiglianza con Objective-C, anche se quest’ultimo non contempla internal.

Continua...

Very short trick: come usare NSFileManager

Apple consiglia di utilizzare l’istanza dell’oggetto NSFileManager e non il suo meotodo di classe defaultManager, in quanto quest’ultimo restituisce un’instanza singleton, cioè sempre lo stesso puntatore ad oggetto (non thread safe).

Continua...

Objective-C: subclassing e Categorie

In Objective-C è possibile estendere una classe data in due modi: eseguendo un classico subclassing (leggi anche ereditarietà) o sfruttando le cosiddette Categorie.

Nota: esiste anche una terza via in Objective-C indicata con nome di Posing che potremmo definire un mix di subclass (perché definisce un nuovo nome) e Categorie (perché da un dato momento tutte le classi di un tipo si comportano come la nuova).

Continua...

Objective-C: esporre proprietà in una classe

Vorrei mostrare e discutere alcuni esempi sul come aggiungere e manipolare proprietà in una Classe Objective-C. Un esempio classico, per l’appunto, è il seguente; nella definizione della nostra interfaccia di classe definiamo due proprietà nome e cognome:

1
2
3
4
5
6
7
8
9
10
11
// MyClass.h
#import <Foundation/Foundation.h>

@interface MyClass : NSObject {
    NSString *nome;
    NSString *cognome;
}

@property (retain) NSString *nome;
@property (retain) NSString *cognome;
@end

Nel file di implementazione inseriamo la dichiarazione @synthesize in modo tale che Xcode produca per noi i metodi getter e setter usati rispettivamente per leggere ed impostare le nostre due proprietà:

1
2
3
4
5
6
7
8
// MyClass.m
#import "MyClass.h"

@implementation MyClass

@synthesize nome, cognome;

@end

Quando andremo ad utilizzare la nostra classe MyClass, cioè quando istanziaremo un oggetto di tipo MyClass, possiamo scrive:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// qualsiasi altra classe, come AppDelegate
// nel file .h
#import <UIKit/UIKit.h>
#import "MyClass.h"

@class TestViewController;

@interface TesAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    TestViewController *viewController;

    MyClass *miaClasse;
}

// nel file .m
miaClasse = [MyClass alloc];
miaClasse.nome = @"Giovambattista";
NSLog(@"miaClasse.nome = %@", miaClasse.nome);

Oppure, che è equivalente:

1
2
3
// sempre nel file .m
[miaClasse setNome:@"Undolog"];
NSLog(@"miaClasse.nome = %@",[miaClasse nome]);

Fin qui tutto bene. Tuttavia potrebbe fuorviare l’equivalenza delle “variabli” interne (ivar) con il nome della proprietà vera e propria. Per capire la differenza, ripropongo lo stesso esempio facendo a meno, questa volta, di @synthesize. Ora, quindi, dovremmo occuparci noi di scrivere i metodi getter e setter. Per sottolineare ulteriormente le differenze, rinominerò le variabili interne inserendo un underscore davanti al nome. Ma vediamo il codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import <Foundation/Foundation.h>

@interface MyClass : NSObject {
    NSString *_nome;
    NSString *_cognome;
}

- (NSString *) nome;                               // get
- (NSString *) cognome;                            // get

- (void) setNome: (NSString *)stringaIngresso;     // set
- (void) setCognome: (NSString *)stringaIngresso;  // set

@end

A differenza dell’esempio precedente i puntatori alla variabili interne (incapsultate) sono diventati _nome e _cognome. Inoltre troviamo quattro definizioni di metodi che rappresentano le nostre get e set. @property è scomparso, in quanto non serve più.
Vediamo il file di implementazione MyClass.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import "MyClass.h"

@implementation MyClass

// get per "nome"
- (NSString *) nome {
    return _nome;
}
// set per "nome"
- (void) setNome: (NSString *)stringaIngresso {
    _nome = stringaIngresso;
}

// get per "cognome"
- (NSString *) cognome {
    return _cognome;
}
// set per "cognome"
- (void) setCognome: (NSString *)stringaIngresso {
    _cognome = stringaIngresso;
}

@end

Una classe così scritta potrà essere utilizzata esattamente come la precedente, cioè:

1
2
3
4
5
6
7
8
miaClasse = [MyClass alloc];
miaClasse.nome = @"Giovambattista";
NSLog(@"miaClasse.nome = %@", miaClasse.nome);

// Oppure, che è equivalente:

[miaClasse setNome:@"Undolog"];
NSLog(@"miaClasse.nome = %@",[miaClasse nome]);

A livello didattico l’abbandono di @synthesize ci ha costretto a scrivere “da soli” i metodi di get e set, evidenziando – anche con l’aggiunta dell’underscore – le differenze tra il nome della proprietà e la sua ivar interna _nome.
A livello funzionale l’uso dei metodi personali get e set permette un reale controllo del dato prima della sua impostazione (o prima della sua lettura) e quindi un reale incapsulamento per proteggere la variabile interna.
Ad esempio sarebbe possibile impedire il passaggio di stringhe vuote alla proprietà nome:

1
2
3
4
- (void) setNome: (NSString *)stringaIngresso {
    if( stringaIngresso == @"" ) stringaIngresso = @"senza nome";
    _nome = stringaIngresso;
}

Ulteriore variante

Se desiderate utilizzare le variabili interne con l’underscore davanti (chi rpoviene da Adobe Actionscript potrebbe essere abituato così) non è necessario abbandonare l’uso della direttiva @synthesize. Xcode permette infatti di “fondere” i metodi sopra indicati:

1
2
@synthesize nome = _nome;
@synthesize cognome = _cognome;

Così facendo potremmo usare internamente il puntatore a _nome, “sintetizzato” – verso l’esterno – come proprietà nome. Inoltre, se è vero che l’uso di @synthesize produce la generazione automatica dei metodi (messaggi) di getter e setter, è vero anche che lo fa solo se non li trova, quindi se desiderate “implementare” un vostro metodo di getter e/o setter potete farlo anche se avete usato la direttiva @synthesize.

Allocazioni di memoria

Negli esempi di sopra ho omesso alcuni dettagli importanti ai fini di una reale implementazione. Prima di tutto non ho illustrato nessun metodo init(), utile ai fini dell’inizializzazione dell’oggetto e dei sui valori di default. Inoltre, manca l’aggiunta di un metodo dealloc():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// file MyClass.m
#import "MyClass.h"

@implementation MyClass

- (id) init {
    if ( self = [super init] ) {
        _nome = @"Nome preimpostato";
        _cognome = @"Cognome preimpostato";
    }
    return self;
}

- (void) dealloc {
    [_nome release];
    [_cognome release];
    [super dealloc];
}

- (NSString *) nome {
    return _nome;
}
- (void) setNome: (NSString *)stringaIngresso {
    if( stringaIngresso == @"" ) stringaIngresso = @"senza nome";
    _nome = stringaIngresso;
}

- (NSString *) cognome {
    return _cognome;
}
- (void) setCognome: (NSString *)stringaIngresso {
    _cognome = stringaIngresso;
}

@end

In futuro vedremo poi i dettagli sulle proprietà readonly, retain, etc… :)

Continua...

WordPress: migliorare la lista dei commenti

Il template standard di WordPress (come altri) normalmente preve un layout alternato per la lista dei commenti. Nel template standard di esempio è impostata una classe css alt, secondo la logica:

1
2
3
4
5
// file comments.php
<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
[...]
/* Changes every other comment to a different class */
$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';

Questo fa si che nel tag li $oddcomment sia impostato una volta a vuoto ("") e una volta a class="alt". Una modifica utile potrebbe essere quella di introdurre un ulteriore classe quando è l’autore del blog a commentare un post:

image

Io, ad esempio, ho usato il seguente codice nel file comments.php:

1
2
3
4
5
<?php
    $authcomment = ($comment->user_id==3)?' authcomment':'';
    $classcomment = ( empty( $classcomment ) ) ? ( ($authcomment=='')?' alt':'' ) : '';  
?>
<li class="<?=$classcomment?><?=$authcomment?>" id="comment-<?php comment_ID() ?>">

La riga $comment-&gt;user_id==3 può variare in base all’ID del vostro utente. Io, ad esempio, non uso l’amministratore per rispondere sul blog, ma ho un mio utente con ID=3. Normalmente l’ID dell’amministratore è 1, se usate questa utenza potete scrivere: $comment-&gt;user_id==1. In questo modo oltre ad avere l’alternanza di layout sui commenti lasciati dai visitatori, risulta immediatamente riconoscibile la risposta dell’autore del blog.

Continua...

WordPress: modifcare AdminBigWidth per gli sviluppatori

AdminBigWidth è un Plugin per WordPress in grado di impostare l’area di lavoro dell’amministrazione a tutto schermo. È un plugin davvero semplice e banale, infatti il suo codice non fa altro che modificare la classe CSS .wrap:

1
2
3
4
function AdminBigWidth () {
    echo '<style type="text/css">.wrap{max-width:none}</style>';
}
add_action('admin_head','AdminBigWidth');

Per chi come me usa l’editor di WordPress in modalità HTML potrebbe risultare utile impostare dei caratteri a spaziatura fissa, come il Courier, invece del font proposto di default. In questo modo, almeno per gli sviluppatori, risulta più facile allineare codici sorgenti. Per fare questo basta aggiungere, sullo stile di AdminBigWidth, una nuova impostazione CSS che si rifletta sull’editor quando è in modalità HTML. Si potrebbe scrivere un Plugin (di due righe) per fare questo, tuttavia è meglio sfruttare proprio il codice di AdminBigWidth, così da evitare un ulteriore carico dovuto all’ennesimo Plugin:

1
2
3
4
function AdminBigWidth () {
  echo '<style type="text/css">.wrap{max-width:none}#editorcontainer #content{font-family:"Courier New", Courier, monospace}</style>';
}
add_action('admin_head','AdminBigWidth');

Continua...

Una classe countDown in Javascript

Nel post 3D CountDown con FIVe3D (vedi anche How I Did It: scrivere un countdown in Flash), veniva proposta una classe per la creazione di un oggetto CountDown in Actionscript, eccone una versione simile in Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * CountDown Class
 *
 * @author        Giovambattista Fazioli
 * @email         g.fazioli@undolog.com
 * @web           http://www.undolog.com
 *
 * @param    dd   (string) 'month day, year'
 *
 */

function countDown( dd ) {
    // init target time
    var target            = new Date( dd );
    this.targetTime        = target.getTime();
   
    /**
     * refresh countdown
     */

    this.refresh = function() {
        var today                 = new Date();
        var currentTime           = today.getTime();
        // time left
        this._leftMilliseconds    = (this.targetTime - currentTime);
        this._leftSeconds         = Math.floor( this._leftMilliseconds / 1000 );
        this._leftMinutes         = Math.floor( this._leftSeconds / 60 );
        this._leftHours           = Math.floor( this._leftMinutes / 60 );
        // no module
        this.leftDays             = Math.floor( this._leftHours / 24 );
        // for print
        this.leftMilliseconds     = this._leftMilliseconds % 1000;
        this.leftSeconds          = this._leftSeconds % 60;
        this.leftMinutes          = this._leftMinutes % 60;
        this.leftHours            = this._leftHours % 24;
    }
    this.refresh();
}

Esempio

1
2
3
var cd = new countDown( '1 1, 2009' );
// mostra quanti giorni, ore, minuti, secondi e millisecondi al primo gennaio 2009
document.write( cd.leftDays + "," + cd.leftHours + "," + cd.leftMinutes + "," + cd.leftSeconds + "," + cd.leftMilliseconds );

Continua...

Actionscript 3.0: tutto con l’operatore new

Sempre nell’ottica di “uniformare”, come già accaduto con gli eventi (vedi La nuova gestione degli eventi di Flash CS3 e Flash CS3: la nuova gestione degli eventi), una delle tante novità presenti in Actionscript 3.0 è la scomparsa di tutti quei metodi ad hoc dedicati alla creazione di particolari oggetti, come: createEmptyMovieClip() o il famosissimo attachMovie(). Con Actionscript 3.0 l’operatore new è sufficiente a svolgere tutte le operazioni di creazione. Un nuovo MovieClip, ad esempio, viene creato (runtime) con il seguente codice:

1
2
var mioClip:MovieClip = new MovieClip();
addChild(mioClip);

image Ma veniamo al dunque! Se ho un simbolo nella libreria e voglio aggiungerlo runtime come procedo se attachMovie() è scomparso? La soluzione non è molto dissimile da quello che accadeva in Actionscript 2.0. Prima di tutto bisogna andare nel pannello di libreria, selezionare il simbolo e aprire la finestra proprietà. A questo punto spuntare la casella di concatenamento Esporta per ActionScript – come accadeva in Flash 8. Un simbolo di libreria ha sempre come Classe base flash.display.MovieClip, ma questo non ci interessa granchè. La cosa interessante, invece, è il parametro Classe che viene impostato di default (quando si spunta Esporta per ActionScript) con il nome del simbolo. Quello che è importante sottolineare è che questa è una nuova modalità di Flash CS3 (e quindi ActionScript 3.0). Il simbolo, per essere esportato, deve avere una Classe di riferimento. La curiosità risiede nel fatto che non siamo costretti a creare per forza una nostra Classe (estesa da flash.display.MovieClip), anche se potremmo farlo.

Continua...



Stop SOPA