2010-05-06 16 views
30

Bir dize değişmezleri grubuyla bir NSArray oluşturmaya çalışıyorum, ancak derleme hatası "Initializer elemanı sabit değil".Dize değişmezleriyle nasıl NSArray oluştururum?

NSArray *currencies = [NSArray arrayWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 

Birisi yanlış yaptığımı işaret edebilir ve hata iletisini açıklayabilir mi?

+0

Kodunuz çalışmalı, hatanın başka bir yerde olmadığından emin misiniz? – pheelicks

+0

Bu satırı nereye koyduğunuzu söylemelisiniz çünkü bir yönteme koymadığınıza benziyor. – malhal

cevap

18

Bu, NSArray oluşturmanın kendisiyle ilgili bir sorun değildir (bunun yerine, [NSArray array] yazdıysanız aynı hatayı alırsınız), ancak yazdığınız yerde. Bunun global ya da dosya-statik bir NSArray olduğunu tahmin ediyorum. C'de, bu tür bir değişkenin sabit bir başlatıcıya sahip olması gerekir - yani bir işlev çağrısı (ya da uzantı olarak bir yöntem çağrısı) anlamına gelir. Çözüm, dizinin gerçek oluşturulmasını ve atanmasını initialize gibi diziye ihtiyaç duymadan önce çağrılacak bir yönteme koymaktır.

+1

Bunu başlık dosyasında bildirdim, ancak bunu bir yöntemin dışında başlatamadığımın farkında değildim. – Kyle

+0

, '+ load' içine koymak güvenli midir? – user102008

0

Bu kodda bir sorun yok. Hatanın bu satırda üretildiğinden emin misiniz?

2

Ben objektif-c bir acemi değilim, ama doğru kod olduğunu düşünüyorum:

NSArray * para = [[NSArray alloc] initWithObjects: "Dolar" @ "Euro" @, @ "Pound", sıfır);

Emin değilim.

+2

Bu da geçerlidir, ancak OP'nin kodunda bir sorun yoktur. Yöntemeniz sadece diziyi korur, oysa – pheelicks

+0

değil. Statik bir değişkende saklanan nesne ** korunmamışsa, gizlenen bir crasher hatasıdır, bu yüzden atama/init yapmak doğru olan şey olacaktır. – jlehr

7

Chuck'ın sorunu tespit ettiği anlaşılıyor. Çözümünüzün kodlanması konusunda bilmeniz gereken bir şey de, statik bir değişkendeki otomatize edilmiş bir NSArray örneğini saklamaktan kaçınmaktır. Ayrıca, bu durumlar için ortak bir model şöyle statik değişkende saklanan değer yaratır ve döndüren bir sınıf yöntemi yazmaktır:

+ (NSArray *)currencies 
{ 
    static NSArray *_currencies; 

    // This will only be true the first time the method is called... 
    // 
    if (_currencies == nil) 
    { 
     _currencies = [[NSArray alloc] initWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 
    } 

    return _currencies; 
} 
+0

Merhaba, neden otomatikleştirilmiş nesneleri statik değişkenler içinde saklamanız önerilmez? Verimlilik için mi, böylece her döngüde korunmalarını istememeleri isteniyor mu? –

+1

Bir otoritease havuzundaki nesneler, korunma sayılarını sormaz; autorelease havuzu bırakıldığında bir 'release' mesajı gönderilir.Bir otomatikleştirilmiş nesne statik bir değişkende saklanırsa, değişken bir kez bu olduğunda geçersiz bir adres içerecek ve başvurunuzu yapmaya çalışacak ya programınızı çökertecek ya da daha da kötüsü, daha önce ayrılmış olan yeni bir nesneye yanlış bir şekilde erişmesine neden olacaktır. Aradaki adres. – jlehr

+0

Evet, bu doğrudur, dokümanlar ayrıca, bir otomatikleştirme nesnesine sahip olursanız, havuzunuz boşaltıldığında nesnesinin ayrılmayacağını belirtir. Appkit'i kullanırsanız, her etkinlik döngüsünde bir otomatik kaldırma havuzu oluşturulur ve sonunda boşaltılır. Bence bu sayıyı koruyalım. –

3

bu eski olmasına rağmen, Apple için yeni bir yama kararlı olduğunu fark edin llvm projesi, NSArray, NSDictionary ve NSNumber için yeni Objective-C literal sözdizimi için destek ekliyor.

NSArray *currencies = @[@"Dollar", @"Euro", @"Pound"]; 

Ve evet bu bir yöntemle içinde olmalıdır:

here ve here

67

bu sihri deneyin bakın.

+0

Yöntemin içinde bulunuyorsa, dinamik olarak ayrılmış dizi olacağına dikkat edin. Statik sabit dizi olarak olmasını bekledim. – Andy