Per prima cosa lanciamo Xcode e creiamo una nuova applicazione di tipo Cocoa Application che chiameremo iMemory.

Fatto questo nell’albero del progetto selezioniamo il file MainMenu.xib e clicchiamo sulla oggetto Window, come mostrato in figura.

Ora aggiungiamo alla view gli oggetti come mostrato in figura.

Ora che abbiamo finito di preparare il layout della nostra applicazione, iniziamo con lo scrivere un po’ di codice. Per prima cosa creiamo una nuova classe di tipo NSObject che chiameremo AppController. Aggiungiamola a MainMenu.xib come mostrato in figura, avendo cura di referenziare il nostro nuovo oggetto (il cubo blu) alla classe appena creata.

Modifichiamo quindi il file di intestazione (.h) della classe AppController nel seguente modo :

Subito dopo #import <Foundation/Foundation.h> aggiungiamo #import <Cocoa/Cocoa.h> quindi  il seguente codice :

#define GiB (1024*1024*1024)        // 1 Gibibyte di RAM
@interface AppController : NSObject{
 //Totale Memoria Ram Installata sul computer
    IBOutlet NSTextField *ramInstallata;
//Memoria ancora libera
    IBOutlet NSTextField *ramLibera;
//Memoria ancora wired
    IBOutlet NSTextField *ramWired;
//Memoria ancora inattiva
    IBOutlet NSTextField *ramInattiva;
//Memoria ancora Attiva
    IBOutlet NSTextField *ramAttiva;

//Per il calcolo della dimensione della memoria libera, wired, inattiva e attiva

//Struttura contenente le informazioni relative alla situazione della memoria
    vm_statistics_data_t    vm_stat;
//Dimensione di una pagina di memoria
    vm_size_t vm_size;
//Port per accedere alle chiamate Mach-Os  per sapere quanta Ram c'e' installata
    mach_port_t myHost;
//Dimensione della memoria installata in GiB
    double nInstalledMemory;
//Dimensione della memoria libera in MiB
    double nFreeMemory;
//Dimensione della memoria inattiva in MiB
    double nInattivaMemory;
//Dimensione della memoria attiva in MiB
    double nAttivaMemory;
//Dimensione della memoria wired in MiB
    double nWiredMemory;

//Timer per aggiornare informazioni sulle memorie
    NSTimer *updateFreeMemory;

}
//Leggo informazioni statistiche relative alla Ram
- (void) memoryStatisticst;
//Chiamata in automatico appena il file NIB viene caricato in memoria
- (void) awakeFromNib;
//Metodo richiamato dal timer che ho impostato allo scadere del tempo previsto
- (void)timerFireMethod:(NSTimer*)theTimer;

@end

Una volta terminato di modificare il file AppController.h, colleghiamo i vari IBOutlet ai rispettivi oggetti in MainMenu.xib.

Passiamo ora ad implementare i metodi in AppController.m. Per prima cosa aggiungiamo, subito dopo #import”AppController.h”, le seguenti righe :

#include<sys/sysctl.h>

#import <mach/mach_host.h>;

Fatto questo possiamo iniziare ad implementare i metodi.

Metodo AwakeFromNib

//Chiamata in automatico appena il file NIB viene caricato in memoria
- (void) awakeFromNib
{
//Inizializzo le variabili di lavoro
    nInstalledMemory=0.0;
    nFreeMemory=0.0;

//Chiamo la funzione per il calcolo delle statistiche sulla memoria
    [self memoryStatisticst];

//Creo un timer per aggiornare ogni secondo la situazione della Ram Libera
    updateFreeMemory=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];
}

Metodo timerFireMethod

- (void)timerFireMethod:(NSTimer*)theTimer
{
//Chiamo la funzione per il calcolo delle statistiche sulla memoria
    [self memoryStatisticst];
}

Metodo memoryStatisticst

- (void) memoryStatisticst{
    //-------------------------------------------------------------------------
    // Memoria Installata
    //-------------------------------------------------------------------------
    int error = 0 ;
    uint64_t value = 0 ;
    unsigned long length = sizeof(value) ;
    int selection[2] = { CTL_HW, HW_MEMSIZE } ;
    error = sysctl(selection, 2, &value, &length, NULL, 0) ;
    if ( error == 0 ){ //Ok, ho il valore il bytes lo trasformo in GiB
        nInstalledMemory=((double)value / GiB);
    }else{
        nInstalledMemory=0.0;
    }
    //-------------------------------------------------------------------------
    
    //-------------------------------------------------------------------------
    // Memoria Libera e altre
    //-------------------------------------------------------------------------
    myHost = mach_host_self();
    if(host_page_size(mach_host_self(), &vm_size) != KERN_SUCCESS) {
        NSLog(@"Errore durante esecuzione di host_page_size");
        vm_size = 4096; //Valore di default
    }    
    mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
    if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &count) != KERN_SUCCESS) {
        NSLog(@"Errore durante esecuzione di host_statistics");
        nFreeMemory=0.0;
    }else{
        nFreeMemory=((double) (vm_stat.free_count) * vm_size) /(1024*1024);
        nAttivaMemory=((double) (vm_stat.active_count) * vm_size) /(1024*1024);
        nWiredMemory=((double) (vm_stat.wire_count) * vm_size) /(1024*1024);
        nInattivaMemory=((double) (vm_stat.inactive_count) * vm_size) /(1024*1024);
    }
    //-------------------------------------------------------------------------    
    
    //Aggiorno informazioni utente
    [ramInstallata setStringValue:[NSString stringWithFormat:@"%.2f GiB",nInstalledMemory]];
    [ramLibera setStringValue:[NSString stringWithFormat:@"%.2f MiB",nFreeMemory]];
    [ramWired setStringValue:[NSString stringWithFormat:@"%.2f MiB",nWiredMemory]];
    [ramAttiva setStringValue:[NSString stringWithFormat:@"%.2f MiB",nAttivaMemory]];
    [ramInattiva setStringValue:[NSString stringWithFormat:@"%.2f MiB",nInattivaMemory]];
}

Bene, abbiamo concluso la nostra applicazione. Se abbiamo fatto tutto correttamente facendo Build & Run vedremo comparire la finestra con indicato lo stato attuale della memoria.