Prelude: Precompiler yönergeleri ve gerçek sabitler arasındaki farkı anlamak için öder. Bir #define
sadece derleyici kodu oluşturmadan önce bir metin değişimi yapar. Bu, sayısal sabitler ve yazım hataları için harika çalışır, ancak işlev veya yöntem çağrıları için her zaman en iyi fikir değildir. Gerçekten doğru bir sabit olmasını istediğiniz varsayımı altında çalışıyorum, yani arama yolunu oluşturan kodun yalnızca bir kez çalıştırılması gerekir. senin MyClass.m dosyasında
, değişken tanımlamak ve bu yüzden böyle bir +initialize
yönteminde bunu doldurmak:
static NSArray *documentsDir;
@implementation MyClass
+ (void) initialize {
if (documentsDir == nil) {
documentsDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) lastObject] retain];
}
}
...
@end
static
değiştirici sadece derleme içinde görünür kılan beyan edildiği birim. Basit bir sabit için, ihtiyacınız olan her şey bu.
sınıf alt sınıflarını varsa, documentsDir
kendisine atamadan önce nil
olup olmadığını kontrol etmek isteyeceksiniz böylece bellek sızıntısı kalmamak, +initialize
, (varsayılan olarak), her alt sınıf için bir kere çağrılır. (Veya Peter Lewis'in işaret ettiği gibi, şu anda başlatılmış olan sınıfın, veya -isMemberOfClass:
yöntemini kullanarak MyClass olduğunu kontrol edebilirsiniz.) Alt sınıflar da doğrudan sabite erişmeye ihtiyaç duyarsa, önceden bildirmeniz gerekir. (çocuk sınıfları dahil) MyClass.h dosyada extern
gibi değişken: Eğer extern olarak değişken önceden bildirirseniz
extern NSArray *documentsDir;
@interface MyClass : NSObject
...
@end
, sen derleme önlemek için tanımından static
anahtar kelime kaldırmalısınız hatalar. Bu gereklidir, böylece değişken çoklu derleme birimlerini kapsayabilir. (Ah, C sevinçleri ...)
Not: Objective-C kodunda, extern
olarak bir şey bildirmek için iyi bir yol kullanmaktır OBJC_EXPORT
(a #define
<objc/objc-api.h>
ilan) set dayandığı C++ kullanıp kullanmadığınızı belirtin. extern
'u OBJC_EXPORT
ile değiştirin ve işiniz bitti.
Düzenleme: Sadece related SO question üzerine oldu.Sadece rağmen,
+(NSString *) getDocumentsDir {
static NSString *documentsDir = nil;
if (!documentsDir) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
documentsDir = [paths objectAtIndex: 0];
}
return documentsDir;
}
"statik" documentsDir etkin bir küresel değişkendir derleyici söyler:
Teşekkürler ama benim proje oluştururken, aşağıdaki uyarıyı alıyorum: 'searchpath' tanımlı ama kullanılmaz. Uyarı, doğrudan kullanıldığı yerlerde hariç tüm dosyalarda görünür. Tanımlanmış bir sabitin bulunduğu dosya precolmpiled başlıklarına dahil edilir. Bu uyarıdan kurtulmanın bir yolu var mı? Teşekkürler. –
Bunun nedeni, sembolün birden çok dosyaya içe aktarılmalarıdır. Söz konusu dosya birçok dosyaya dahil edildiğinden, alt sınıflar hakkındaki rehberimi kullanın - değişkeni üstbilgide extern olarak ilan edin, sonra statik olarak bildirmek için yalnızca bir yer (.m dosyasında) seçin ve (muhtemelen farklı) yerleştirmek için yer. Şimdiden bunu yapıyorsanız ve hata devam ederse, derleyiciye kullanılmayan sembollerle ilgili uyarıları bastırması için __attribute __ ((kullanılmamış)) ile değişken bildirimini önekleyin. (Kişisel olarak #define UNUSED __attribute __ ((kullanılmamış)) bunun için kısayol olarak kullanıyorum.) –
Not: Eğer MyClass alt sınıflanmış ise, başlatma birden çok kez çağrılacak, eğer başlatılacaksa, kullanmanız gerekecek: if (self == [Sınıfım sınıf]) { searchPath == ...; } –