2014-06-20 20 views
15

Hızlı-sıralı komut satırı yardımcı programının farkındayım. Swift'in kendisinden yapmamı sağlayacak bir şey arıyorum.Bir Swift sınıf adını dinamik olarak nasıl sıralayabilirim?

Swift REPL'den :target modules dump symtab çalıştırdıktan sonra bunu gördüğümde heyecan duydum, ancak swift_demangleSimpleClass numaralı telefonu nasıl arayacağımı bilmiyorum.

module dump

, özel Swift fonksiyonları çağıran izin verecek bir @asmname komutu var gibi görünüyor, ama bu işe almak mümkün olmamıştır.

Muhtemelen bunun için normal ifade tabanlı bir çözümleyici yazacağım, ancak Swift çerçevesindeki bir şeyi çağırmak biraz daha güvenli görünüyor.

+0

Şu an için bunu elle ayrıştıracağım. Kod: https://gist.github.com/jpsim/1b86d116808cb4e9bc30 – jpsim

cevap

-1

XCode6 beta 5 sürümünden itibaren, NSStringFromClass otomatik olarak sınıf listelerine döndürülüyor gibi görünüyor, bu nedenle bu kodun artık gerekmemesi gerekiyor.

Orada bunu yapmak için yerleşik bir yolu olmalı, ama kalmayıncaya kadar, bu uzantı hile yapmak gerekir: sınıflar için anı (XCode 6 artı 7 beta) At

import Foundation 

public func demangleClassName(mangled: String) -> String { 
    let scanner = NSScanner(string: mangled) 
    if (!scanner.scanString("_TtC", intoString: nil)) { 
     // not a mangled swift class name: Core Foundation, etc. have no module prefix 
     return mangled 
    } 

    var demangled = "" 
    var len : Int = 0 
    while (!scanner.atEnd && scanner.scanInteger(&len)) { 
     let range = Range(start:advance(mangled.startIndex, scanner.scanLocation), end: advance(mangled.startIndex, scanner.scanLocation + len)) 
     let part = mangled.substringWithRange(range) 
     if (countElements(demangled) > 0) { 
      demangled += "." 
     } 
     demangled += part 
     scanner.scanLocation += len // skip to the next segment that may be prefixed by the number 
    } 

    return demangled 
} 

public extension NSObject { 
    /// demangle the current Swift object's class name, as per mangling description at: http://www.eswick.com/2014/06/inside-swift/ 
    public class func demangledClassName() -> String { 
     return demangleClassName(className()) 
    } 
} 
+0

Bu kodun derlemesi dışında. Daha fazla yorumumu (https://gist.github.com/mprudhom/69ec96f3d95c3d080e6a) – matt

+0

Benim için iyi çalışıyor, hem bir modülde hem de XCode 6 beta 3'teki oyun alanında çalışıyor. içinde, hangi hatayı görüyorsun? –

+1

Asla oyun alanlarını kullanmam.Onu bir uygulamaya yapıştırdım ve ilk satırda 'className()' tanınmadı. – matt

3
func typename (thing:Any) -> String{ 
    let name = _stdlib_getTypeName(thing) 
    let demangleName = _stdlib_demangleName(name) 
    return demangleName.componentsSeparatedByString(".").last! 
} 
+0

_stdlib_demangleName artık mevcut değil. – zneak

2

En üst düzeyde, sadece app adınızı, bir noktanızı ve sınıf adınızı alırsınız.

  1. açıklama hedefinin açılımı _Tt (bundle/uygulama adı) ile başlar: Yani MyApp.MyClass gibi bir şey Ama alt sınıfları kullandığınız an olacak, açıklama aşağıdaki 3 bölüm halinde inşa olduğunu Bundan sonra Sınıf, Protokol veya İşlev anlamına gelen CPF gibi bir veya daha fazla harfe sahip olacaksınız. Bunlar, iç içe geçirme
  2. 'a göre ters sıradadır. Ardından, sayı dizisi ve sayının adın uzunluğu olduğu bir ad alırsınız. Bunların her biri, tarifin başlangıcında belirtilen hedef, Sınıf, Protokol veya Fonksiyon içindir.

İşlevler burada özel bir durumdur. Açıklamanın, işlev imzası hakkında da bazı bilgileri olacaktır.

Örneğin bir _TtCFCC5MyApp7MyClass10MySubClass6myFuncFS0_FT_T_L_11MySubSubClass

Bu aşağıdaki kodda MySubSubClass açıklaması olacağını olabilir:

İşte
class MyClass { 
    class MySubClass { 
    func myFunc() { 
     class MySubSubClass { 
     } 
    } 
    } 
} 

kullanmak kolay içine bu tarife ayrıştırmak olacak bazı sample code bulabilirsiniz özellikleri ve diziler.

Güncelleme: Sıra şimdi hızlıca dönüştürülüyor. Burada bulabilirsiniz: https://github.com/mattgallagher/CwlDemangle/blob/master/CwlDemangle/CwlDemangle.swift

İlgili konular