Domanda

ho visto molti sviluppatori che aggiungono diverse macro convenienza per l'Prefix.pch dei loro progetti iOS.

Cosa fare (o non) si consiglia di aggiungere al file di iOS Prefix.pch? Che cosa significa il vostro look Prefix.pch come?

È stato utile?

Soluzione

Ewww ... non mettere le macro in un file .PCH! Un file .PCH è, per definizione, uno specifico progetto di intestazione precompilata. In realtà non dovrebbe essere utilizzato al di là del contesto del progetto e in realtà non dovrebbe contenere qualsiasi cosa, ma #includes e #imports.

Se si dispone di alcuni macro e in modo tale che si desidera condividere tra le intestazioni, poi bastone 'em in un file di intestazione della propria - Common.h o qualsiasi altra cosa - e #include che all'inizio del. pch.

Altri suggerimenti

Per iOS moderna e OS X, la gente dovrebbe usare Moduli . Questo è abilitata di default per i nuovi progetti, e importare / inclusione viene eseguita utilizzando @import.

I moduli permettono al compilatore di creare una rappresentazione intermedia del contenuto di un modulo (per esempio un header del quadro). Molto simile a un PCH, questa rappresentazione intermedia può essere condiviso tra più traduzioni. Ma moduli prendono un ulteriore passo avanti perché un modulo non è necessariamente specifico bersaglio, e le loro dichiarazioni non deve essere localizzata (per un *.pch). Questa rappresentazione si può risparmiare un sacco di lavoro ridondante compilatore.

Utilizzando i moduli, non hanno bisogno di un PCH, e probabilmente dovrebbe solo farla finita con loro del tutto - a favore dell'uso di @import locale per la dipendenza. In tal caso, un PCH è solo risparmiando da digitazione inclusioni locali alle dipendenze (che IMO si dovrebbe fare in ogni caso).

Ora, se guardiamo indietro alla domanda iniziale: Si dovrebbe evitare di riempire il vostro PCH con ogni sorta di cose a caso; Le macro, costanti, #defines, e ogni sorta di piccoli biblioteche. In generale, si dovrebbe omettere ciò che è veramente inutile la maggior parte dei file di origine . Mettere tutti i tipi di roba in PCH è solo l'aggiunta di un po 'di peso e di dipendenza. Vedo la gente mette tutto quello che collegano e di più per la PCH. In realtà, i quadri ausiliari in genere solo bisogno di essere visibile ad alcune traduzioni in maggior parte dei casi. Per esempio. "Ecco la nostra roba StoreKit - ha lasciati importazione StoreKit solo dove deve visibile In particolare, questi 3 traduzioni.". Questo mantiene i tempi di costruzione verso il basso, e ti aiuta a tenere traccia delle vostre dipendenze, in modo che si può riutilizzare il codice più facilmente. Quindi, in un progetto objC, che di solito fermarsi a Fondazione. Se c'è un sacco di interfaccia utente, allora si potrebbe prendere in considerazione l'aggiunta di UIKit o AppKit al PCH. Tutto questo è supponendo che si desidera ottimizzare i tempi di compilazione. Uno dei problemi con grandi PCHS che includono (quasi) tutto è che la rimozione delle dipendenze inutili è molto tempo. Una volta che le dipendenze del vostro progetto e crescono i tuoi tempi di costruzione salire, è necessario combattere eliminando le dipendenze non necessarie al fine di ridurre i tempi di costruzione. Inoltre, tutto ciò che cambia spesso dovrebbe generalmente essere tenuto fuori dalla vostra PCH. Un cambiamento richiede una completa ricostruzione. Ci sono alcune opzioni per PCHS azionari. Se si utilizza PCHS, non mirano alla condivisione di supporto.

Per quanto riguarda quello che ho messo nel mio PCH: ho smesso di usarli per la stragrande maggioranza dei bersagli anni fa. Non solo di solito non è abbastanza in comune per qualificarsi. Tenete a mente, scrivo C ++, objC, objC ++ e C - le emette compilatore uno per ogni lingua nella vostra destinazione. Quindi consentendo loro spesso portato a tempi di compilazione più lenti e più elevato di I / O. In ultima analisi, l'aumento della dipendenza non è un buon modo per combattere la dipendenza in progetti complessi. Lavorare con più lingue / dialetti, ci sono molto variazione nelle dipendenze richieste per un determinato obiettivo. No, non vorrei consigliare che come ottimale per ogni progetto, ma questo dare prospettiva al gestione delle dipendenze in progetti di grandi dimensioni.


Riferimenti


Note

  • La domanda è stata originariamente chiesto qualche anno prima dell'introduzione Moduli.
  • Attualmente (Xcode 5.0), moduli lavorano per C e objC, ma non C ++.

Sono d'accordo con bbum. La mia opinione sul file PCH è che dovrebbe contenere praticamente solo dichiarazioni #include o #import. Quindi, se avete un po 'di utili, le macro di alto livello, definirli in qualcosa di simile Common.h e #import quel file, come suggerito bbum.

Io di solito fare un passo ulteriore e utilizzare il file PCH per #import un file chiamato XXCategories.h (dove XX è la convenzione di denominazione prefisso di classe si utilizza) che contiene #imports per tutta la mia UIKit e Fondazione categorie di classe: NSString+XXAdditions.h, UIColor+XXAdditons.h, etc.

creare un file di intestazione "macros.h"

importare questa intestazione in Prefix.pch

In questo macros.h mettere tutti i quadri e altre cose importanti.

Se siete preoccupati per le prestazioni, non ti preoccupare, guarda cosa Apple dice:

intestazioni e delle prestazioni

  

Se siete preoccupati che tra cui un file di intestazione principale può causare il   programma per gonfiare, non ti preoccupare. Poiché le interfacce OS X sono implementate   utilizzando gli schemi, il codice per tali interfacce risiede in una dinamica   libreria condivisa e non nel vostro eseguibile. Inoltre, solo il codice   utilizzata dal programma è mai caricato in memoria in fase di esecuzione, in modo che il   in-memory footprint rimane altrettanto piccolo.         Per quanto riguarda tra cui un gran numero di file di intestazione durante la compilazione, ancora una volta, non ti preoccupare. Xcode fornisce un precompilato   impianto di intestazione per accelerare i tempi di compilazione. Compilando tutti i   intestazioni quadro in una volta, non v'è alcuna necessità di ricompilare le intestazioni   a meno che non si aggiunge un nuovo quadro. Nel frattempo, è possibile utilizzare qualsiasi   interfaccia dalla quadri inclusi con poca o nessuna prestazione   penalità.

anche nel mio macros.h ho messo un sacco di costanti come:

// delegate
#define UIAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]
#define APPDELEGATE   ((AppDelegate *)[[UIApplication sharedApplication] delegate])

// system
#define IS_IPHONE_4INCH (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height==568)
#define IS_IPAD                     (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

// screen size
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_4 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 480.0)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreen mainScreen] nativeScale] == 3.0f)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)
#define IS_RETINA_DISPLAY ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))
#define IS_PORTRAIT                 UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])
#define IS_LANDSCAPE                UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])

//system version
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)

// math
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))

// cores
#define RGB(r,g,b)    [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
#define MAKECOLOR(R, G, B, A) [UIColor colorWithRed:((float)R/255.0f) green:((float)G/255.0f) blue:((float)B/255.0f) alpha:A]
#define MAKECOLORFROMHEX(hexValue) [UIColor colorWithRed: ((float)((hexValue & 0xFF0000) >> 16))/255.0 green:((float)((hexValue & 0xFF00) >> 8))/255.0 blue:((float)(hexValue & 0xFF))/255.0 alpha:1.0]



//customizations
#define SHOW_STATUS_BAR               [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
#define HIDE_STATUS_BAR               [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

#define SHOW_NAVIGATION_BAR           [self.navigationController setNavigationBarHidden:FALSE];
#define HIDE_NAVIGATION_BAR           [self.navigationController setNavigationBarHidden:TRUE];

#define VC_OBJ(x) [[x alloc] init]
#define VC_OBJ_WITH_NIB(x) [[x alloc] initWithNibName : (NSString *)CFSTR(#x) bundle : nil]

#define RESIGN_KEYBOARD [[[UIApplication sharedApplication] keyWindow] endEditing:YES];

#define CLEAR_NOTIFICATION_BADGE                       [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
#define REGISTER_APPLICATION_FOR_NOTIFICATION_SERVICE  [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]

#define HIDE_NETWORK_ACTIVITY_INDICATOR                 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
#define SHOW_NETWORK_ACTIVITY_INDICATOR                 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top