Swift - hangi türleri kullanmalı? NSString veya String


109

Swift'in tanıtımı ile yeni dile kafa yormaya çalışıyorum

Ben bir iOS geliştiricisiyim ve NSString, NSInteger, NSDictionarybir uygulamadaki gibi türleri kullanırım . Apple'ın "The Swift Programming Language" e-kitabında Swift türlerini kullandıklarını fark ettim.String, Int, Dictionary

Swift türlerinin Foundation türlerinin yaptığı bazı işlevlere sahip olmadığını (veya farklı şekilde adlandırıldığını) fark ettim. Örneğin NSStringbir lengthözelliği var. Ancak Swift için benzerini bulamadım String.

Merak ediyorum, bir iOS uygulaması için hala Foundation türlerini kullanmalı mıyım?


3
Tercih et String. Bununla birlikte, Stringişlevsellik hala alfa sürümünde biraz sınırlıdır, bu nedenle NSStringşimdilik daha fazla kullanılacaktır. GA’ya kadar API’yı düzelteceklerini umuyoruz.
Sulthan

1
Ayrıca, countElements(str)sorunuzun belirli bir bölümünü cevaplamak için arayabilirsiniz .
Nate Cook

Daha da "foo".length" directly in Swift. An implicit cast to iyisi, NSString` çağırabilirsiniz sizin için derleyici tarafından eklendi!
Gabriele Petronella

1
@GabrielePetronella .length özel karakterler için doğru çalışmayabilir. 2 veya 3 unicode karakter alan Emoji veya Çince karakterler gibi. countElements, kullanılacak doğru yöntemdir.
Fogmeister

Yanıtlar:


98

Mümkün olduğunca Swift yerel türlerini kullanmalısınız. Dil, bunları kullanmak için optimize edilmiştir ve işlevlerin çoğu yerel türler ve türler arasında köprüdür Foundation.

İken Stringve NSStringyani çoğunlukla birbirinin yerine, sen geçebilir Stringele yöntemleri içine değişkenleri NSStringtersi, bazı yöntemler otomatik olarak şu andan itibaren köprülenmemelidir görünüyor parametreleri ve yardımcısı. Bkz bu cevabı bir dize uzunluğunu almak için nasıl bir tartışma için ve bu cevabı kullanımıyla ilgili bir tartışma için containsString()altdizgelerin kontrol etmek. (Sorumluluk reddi: Bu yanıtların her ikisinin de yazarıyım)

Diğer veri türlerini tam olarak araştırmadım, ancak yukarıda belirtilenlerin bazı sürümlerinin Array/ NSArray, Dictionary/ NSDictionaryve Swift'deki çeşitli sayı türleri için de geçerli olacağını varsayıyorum.NSNumber

Temel türlerinden birini kullanmanız gerektiğinde, bunları örneğin içinde olduğu gibi değişkenleri / sabitleri açıkça yazmak için var str: NSString = "An NSString"kullanabilir veya örneğin bridgeToObjectiveC()Swift türündeki mevcut bir değişken / sabit üzerinde kullanabilirsiniz str.bridgeToObjectiveC().length. Ayrıca yayınlayabileceğim Stringbir karşı NSStringkullanarak str as NSString.

Bununla birlikte, bu tekniklerin Temel türlerini veya en azından bazılarını açıkça kullanma zorunluluğu gelecekte geçersiz olabilir, çünkü dil referansında belirtilenden , örneğin String/ NSStringköprüsü tamamen sorunsuz olmalıdır.

Konuyla ilgili kapsamlı bir tartışma için Swift'i Kakao ve Objective-C ile Kullanma: Kakao Veri Türleriyle Çalışma konusuna bakın.


4
bridgeToObjectiveC()NSString ve Swift's String arasındaki bağlantıya referans ve açıklama için +1 .
Chris

2
hey cezar, cevabınızı güncellemek isterseniz bridgeToObjectiveC'nin kullanımdan kaldırıldığını düşünüyorum.
Dan Beaulieu

Swift 3 el kitabında, Temel türlerin referans olarak aktarıldığını, yerel türlerin değerle aktarıldığını (veya bu noktada tam olarak anlamadığım bir şey olduğunu) fark ettim. Bunun sonuçlarını tartışarak cevabınızı güncellerseniz harika olur.
Nigel

27

NSString: Yığın içinde bulunan ve her zaman referansla geçen nesneler oluşturur.

String: Her geçtiğimizde bir değer türüdür, değere göre iletilir. Struct ve Enum gibi, String'in kendisi Swift'de bir Struct.

public struct String {
 // string implementation 
}

Ancak geçtiğinizde kopya oluşturulmaz. Onu ilk değiştirdiğinizde bir kopya oluşturur.

Dize, NSString olarak otomatik olarak Objective-C'ye köprülenir. Swift Standard Kitaplığı yoksa, NSString tarafından tanımlanan yöntemlere erişmek için Temel çerçevesini içe aktarmanız gerekir.

Swift String çok güçlüdür, çok sayıda dahili fonksiyona sahiptir.

Dizede Başlatma:

var emptyString = ""             // Empty (Mutable)
let anotherString = String()     // empty String immutable    
let a = String(false)           // from boolean: "false"
let d = String(5.999)           //  "    Double "5.99"
let e = String(555)             //  "     Int "555"
// New in Swift 4.2 
let hexString = String(278, radix: 18, uppercase: true) // "F8"

tekrar eden değerlerden String oluşturun:

 let repeatingString = String(repeating:"123", count:2) // "123123"

Swift 4'te -> Dizeler Karakterlerden Oluşuyor:

Artık String, Koleksiyon türünde herkesin gerçekleştirebileceği tüm işlemleri gerçekleştirebilir.

Daha fazla bilgi için lütfen apple belgelerine bakın.


2
Bu cevap daha fazla oy almalı. Bu, String ve NSString arasındaki temel farktır. Diğer her yerde neredeyse birbirinin yerine kullanılabilirler
Fazla

Mükemmel cevap. özellikle değer ve başvuru türü not.
spnkr

11

Bazıları NSString'in String'e ücretsiz çeviri yaptığını belirttiği gibi, en iyi seçeneğiniz Swift yerel türlerini ve sınıflarını kullanmaktır, ancak bunlar% 100 aynı değildir, örneğin aşağıdakileri alın

var nsstring: NSString = "\U0001F496"
var string: String = "\U0001F496"

nsstring.length
count(string)

string'deki karakterleri saymak için count () yöntemini kullanmanız gerekir, ayrıca uzunluğunu UTF16'ya göre saydığı için nsstring.length'in 2 döndürdüğünü unutmayın.

Benzer, EVET Aynı, HAYIR


7

Stringve NSStringbirbirinin yerine kullanılabilir, bu nedenle hangisini kullandığınız önemli değildir. Kullanarak her zaman ikisi arasında geçiş yapabilirsiniz.

let s = "hello" as NSString

ya da

let s: NSString  = "hello"

NSIntegersadece bir intveya a için bir takma addır long(mimariye bağlı olarak), bu yüzden sadece Int.

NSDictionaryDictionarytamamen ayrı bir uygulama olduğundan farklı bir konudur .

Genel olarak, mümkün olduğunda hızlı türlere bağlı kalırım ve bridgeToObjectiveC()hızlı sınıflar tarafından sağlanan yöntemi kullanarak her zaman ihtiyaç duyduğunuzda ikisi arasında dönüşüm yapabilirsiniz .


IntKitapta Swift'in veri türünün mimarinin kelime boyutu ile aynı olduğu belirtiliyor. NSIntegeraynı zamanda mimarinin kelime boyutu ile aynı boyuttadır.
MaddTheSane

6

Hedef C türleri hala dinamik olarak gönderildiğinden, muhtemelen daha yavaş olacaklar. Object-c API'leri ile etkileşime girmeniz gerekmedikçe, Swift yerel türleri kullanarak en iyi şekilde hizmet edeceğinizi söyleyebilirim.


Evet tam olarak cevap bu. Dinamik olarak gönderilen yöntemlerden ve nesne değişken erişiminden kaçınma, WWDC'de bahsettikleri bu hız iyileştirmelerini yapan tek şeydir. Geçmişte performans konusunda endişelenen herkes, statik dağıtımı elde etmek için C ++ dizesi ve kapsayıcılar kullanıyordu.
Lothar

5

Yapabildiğiniz her an Swift yerel türlerini kullanın. String durumunda, bununla birlikte, bunun NSStringgibi tüm yöntemlere "kesintisiz" erişiminiz vardır :

var greeting = "Hello!"
var len = (greeting as NSString).length

4

Swift 4 güncellemesi

String, hızlı 4'te revizyonlar alıyor. Artık doğrudan sayımı çağırabilir ve grafem kümelerini bir emoji gibi 1 parça olarak kabul edebilirsiniz. NSString güncellenmedi ve bunu başka bir şekilde sayıyor.

var nsstring: NSString = "👩‍👩‍👧‍👦"
var string: String = "👩‍👩‍👧‍👦"

print(nsstring.length) // 11
print(string.count)    // 1

1
NSStrings muhtemelen grafem kümeleriyle başa çıkmak için güncellenmeyecek: Eski davranışa dayanan çok fazla uygulamayı bozacaktır. Ayrıca NSString.lengthUTF16 karakterlerini sayar.
MaddTheSane

0

String bir yapıdır

// Swift Modülünde

public struct String

{

}

NSString bir sınıftır

// Temel Modülünde

açık sınıf NSString: NSObject

{

}

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.