2013-10-15 50 views
19

Treehouse'daki bir eğiticiyi izleyerek, XCode'daki bu popüler Object-C uyarı iletisini görüyorum.nesnel c örtük dönüştürme, tamsayı hassaslığını kaybeder 'NSUInteger'

Benim düğme fonksiyonu

- (IBAction)buttonPressed:(UIButton *)sender { 
    NSUInteger index = arc4random_uniform(predictionArray.count); 
    self.predictionLabel.text = [predictionArray objectAtIndex:index]; 
} 

Ben benzer stackoverflows birkaç birkaç ettik, NSUInteger hattı üzerinde görmek ve onlar 64bit numaraları ve tipi döküm vs 32bit bahsetmek gibi görünüyor, ama nasıl emin Bunu yapmak için mi?

Benim predictionArray

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    predictionArray = [[NSArray alloc] initWithObjects: 
        @"It is certain", @"It is decidely so", @"All signs say YES", @"The stars are not aligned", 
        @"My reply is no", 
        @"It is doubtful", 
        @"Better not tell you now", 
        @"Concentrate and ask again", 
        @"Unable to answer now", nil]; 
// Do any additional setup after loading the view, typically from a nib. 
} 

enter image description here

cevap

67

güvenle bir alçı ile uyarı baskılayabilir.

NSUInteger index = arc4random_uniform((uint32_t) predictionArray.count); 

Bu uyarıları bastırmak için, bu yüzden operasyon güvenli olup olmadığını anlayana kadar uyarılara kurtulmak için bir şeyler döküm gitmez güvenli hep değil.

Burada neler oluyor, platformunuzda NSUInteger, 64 bitlik bir tamsayı türü için bir yazım hatasıdır. Sadece bazı platformlarda her zaman 64 bit değil. Derleyici, bu bitlerin bazılarının atıldığını size uyarıyor. Bu bitlerin önemsiz olduğunu biliyorsanız, sadece bir oyuncu kullanabilirsiniz.

Bu durumda, sonuç index her zaman 2 -1 altında olacaktır. predictionArray'un veya daha fazla öğeyi içermesi için uzaktan mümkün olsa bile, programınızda bir hata vardır ve arc4random_uniform()'un 64 bit sürümünü oluşturmalısınız. Aşağıdaki kod ile bunu sağlayabilir: my comment gereğince

assert(predictionArray.count <= (uint32_t) -1); 
+0

Hmm, Bunu denedim ama hala aynı uyarı. Peki NSUInteger'i ne gibi döküm yapıyorum? '(NSUInteger)' anlamına gelir. Ya da belki daha önemlisi, bana ne hakkında uyarı veriyor? –

+0

@LeonGaban: Oyuncuları yanlış yere koydum. –

+0

Teşekkürler! Hala bunu anlamaya çalışmak, yani 'NSUInteger' her zaman 32 bit int? Bunu 64 bit olarak kullanmaya çalıştım ve aynı hatayı aldım. Bu küçük şeyler benim için yeni, –

11

, arc4random_uniform(), bir u_int32_t bakılmaksızın hedef mimarisinin, her zaman 32 bit işaretsiz bir tamsayı alır ve geri döner. Ancak, predictionArray.count, typedef d 32 bit ve 64 bit sistemler için farklı bir NSUInteger döndürür; 32 bit sistemde 32 bit (unsigned int) ve 64 bit sistemde 64 bit (unsigned long). 64-bit bir sistem üzerinde çalışıyorsanız, 64 bit NSUInteger bir 32 bit tamsayı bekleyecek bir işlev geçirerek, derleyici bitler bittiğine şikayet etmesine neden olur.

+0

Açıklama için teşekkürler, bu yüzden 64 bit işlev/yönteme 32 bit bir sayı gönderirseniz, bu program yavaşlatır mı? Yoksa sadece daha verimli olabileceğimi mi söylüyor? Arc4random_uniform() 'ın 64bit sürümü var mı? Yoksa sadece u_int32_t kullanmalı mıyım? –

+1

@LeonGaban Hiç de fark edilmeyen bir miktar. 32 bit numaranız 64 bit olacak şekilde genişletilmelidir; eğer imzasız ise, o zaman otomatik olarak 0s ile genişletilecek ve eğer imzalı ve negatif ise 1s ile uzatılacaktır. Bu gerçekten sorun değil. Ancak, 64 bitlik bir sayıyı 32 bitlik bir işleve iletmeye çalışırsanız, numaranızın bölümleri dışarı atılabilir (işlev yalnızca 32 bit alır) ve derleyici şikayette bulunur (Bir oyuncuyla ne yaptığınızı bildiğinizden emin olun). –

+0

@LeonGaban Ne yazık ki, 'arc4random *' işlevlerinin 64 bit sürümü yok, ancak bunların içine dökülmeye devam edin ve her şey yolunda gideceksin. Her yerde 'u_int32_t 'kullanılmasını öneriyorum, çünkü tanım gereği, 32 bit. “NSUInteger”, Apple'ın hedef platformuyla eşleşmesi için sizin için typedef'd olmanın avantajına sahiptir, bu sayede her zaman bunu kullanabilir ve verimli bir şekilde yaptığınızı bilirsiniz (keyfiyetinizi sınırlamak istemezsiniz). Veri mantıklı ve gerekli olmadıkça). –