Biçim bağımsız değişkeni olarak kullanıldığında neden bir NSInteger değişkeni uzun süre kullanılmalıdır?


143
NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <==== 

Yukarıdaki kod bir hata üretir:

'NSInteger' türündeki değerler biçim bağımsız değişkenleri olarak kullanılmamalıdır; bunun yerine "uzun" a açık bir döküm ekleyin

Düzeltilen NSLogmesaj aslında NSLog(@"%lg", (long) myInt);. Neden tamsayı değeri dönüştürmek zorunda myIntiçin longben ekrana değeri isterseniz?


1
@DanielLee, kullanmak durumunda NSLog(@"%ld", (long) myInt);, longdöküm onunla maç yapmaktır larasında eleme %ld, ancak bütün bunlar gereksizdir NSLog(@"%d", myInt);(yeterli biz görüyoruz ki göz önüne alındığında myIntdeğil long. Alt satırda, dökme myIntbiçiminde uzun eleme kullanılıyorsa dize, ancak uzun dize biçimi niteleyicisi kullanmaya veya longburada yayınlamaya gerek yok
Rob

1
Görünüşe göre NSLog (@ "% i", myInt); , yukarıda gösterdiğim gibi hata mesajını alacağınız için yeterli.
Daniel Lee

2
@DanielLee Martin R'nin yorumuna bakın. Sen (burada iOS etiketiyle sorunuzu yayınlanmıştır NSIntegerolduğu değil uzunluğunda), ancak (OS X hedef ile topluyoruz gibi geliyor NSInteger ise long ).
Rob

Ahh, anlıyorum. İOS ve OSX'in NSInteger'ı bit ve tipte farklı hale getireceğini bilmiyordum.
Daniel Lee

Yanıtlar:


193

OS X (64 bit) üzerinde derlerseniz bu uyarıyı alırsınız, çünkü bu platformda 64 bit tam sayı NSIntegerolarak tanımlanır long. %iFormatı, diğer yandan, bir int32 bit olan. Böylece biçim ve gerçek parametrenin boyutu aynı değildir.

Yana NSInteger32-bit veya 64-bit, platforma bağlı olarak, derleyici bir atması eklemek için tavsiye longgenellikle.

Güncelleme: iOS 7 şu anda 64 bit'i de desteklediğinden, iOS için derlerken aynı uyarıyı alabilirsiniz.


1
İOS 7'de bu hatayı alıyorum. En son iPhone 5S 64 bit olduğundan, uzun süredir ayarlarsam eski 32 bit cihazlarda herhangi bir soruna neden olur mu?
Pritesh Desai

25
@BartSimpson: "long" için açık bir durumla, olduğu gibi NSLog(@"%ld", (long) myInt)32 bit ve 64 bit üzerinde düzgün çalışır.
Martin R

@MartinR döküm yapıyorsak, neden sadece uzun bir süre kullanmıyorsunuz?
William Entriken

3
@FullDecent: Tabii uzun süredir burada çalışabilirsiniz: long myInt = [myNumber longValue];. Ancak birçok (Core) Foundation yöntemi, parametre veya dönüş değeri olarak NS (U) Tamsayı kullanır, bu nedenle genel sorun devam eder. Ayrıca, uygulamanızda 64 bitlik cihazlarda daha geniş bir aralık elde etmek için NS (U) Tamsayı'yı kullanmak mantıklı olabilir.
Martin R

39

Biçim belirteçleriniz veri türlerinizle eşleşiyorsa hiçbir şeye yayınlamanız gerekmez. NSIntegerYerel türler olarak nasıl tanımlandığına ilişkin ayrıntılar için Martin R'nin cevabına bakın .

64 bit ortamlar için oluşturulması amaçlanan kod için, günlük ifadelerinizi şöyle yazabilirsiniz:

NSLog(@"%ld",  myInt); 

32 bit ortamlar için şunları yazabilirsiniz:

NSLog(@"%d",  myInt); 

ve hepsi kastsız çalışacak.

Yine de dökümleri kullanmanın bir nedeni, iyi kodun platformlar arasında taşınması eğilimindedir ve değişkenlerinizi açıkça kullanırsanız, hem 32 hem de 64 bitte temiz bir şekilde derlenecektir:

NSLog(@"%ld",  (long)myInt);

Ve bunun, sadece sonuçta sadece hata ayıklama yardımcıları olan NSLog ifadeleri için değil, aynı zamanda [NSString stringWithFormat:]üretim kodunun meşru unsurları olan çeşitli türetilmiş mesajlar için de geçerli olduğunu unutmayın.


1
Şimdi bu kesmek gerekli olduğuna göre, ilk etapta NSInteger kullanmak hala en iyi uygulama mı?
William Entriken

@FullDecent Biçim dizeleri gibi yalnızca çalışma zamanında yorumlanan kodda bir sorundur. Bütün derlenmiş kodlar NSInteger typedef'den yararlanır.
Monolo

O ise buna tanım kapsamını tanımlanır neden iyi nedenler vardır, çünkü NSInteger kullanmak en iyi yöntem.
gnasher729

22

Bir NSInteger'ı NSLog'a geçirmek yerine sadece bir NSNumber iletin. Bu, tüm yayınları ve doğru dize biçimi belirleyicisini seçmeyi sağlar.

NSNumber foo = @9000;
NSLog(@"foo: %@", foo);
NSInteger bar = 9001;
NSLog(@"bar: %@", @(bar));

Ayrıca endişelenmenize gerek kalmadan NSUIntegers için de çalışır. 64bit / 32bit karma ortamda NSInteger ve NSUInteger'e verilen cevaba bakın


2
Seçilen cevabın teknik olarak sorunun en iyi cevabı olduğunu varsayalım, ancak her bir olayı nasıl önleyeceğinizi ve uyarıları nasıl önleyeceğinizi bilmek istiyorsanız, bunun en iyi çözüm olduğunu düşünüyorum.
Daniel Wood

0

Kullanırken uyarı tutar NSLog(@"%ld", (long)myInt);, ancak long myInt = 1804809223;iOS 10'da yapılan değişiklik bildirimi sonrasında uyarıyı durdurur .


-2

OS X, 32 ve 64 bit ortamlardaki değerleri temsil etmek için tutarlı bir yol sağlamak üzere NSInteger, NSUInteger, CGFloat ve CFIndex gibi çeşitli veri türlerini kullanır. 32 bit bir ortamda, NSInteger ve NSUInteger sırasıyla int ve unsigned int olarak tanımlanır. 64 bit ortamlarda, NSInteger ve NSUInteger sırasıyla uzun ve imzasız uzun olarak tanımlanır. Platforma bağlı olarak farklı printf tarzı tip belirteçleri kullanma ihtiyacını ortadan kaldırmak için, hem 32 bit hem de 64 bit ortam için bu bağlantıda gösterilen belirteçleri kullanabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.