본문 바로가기

IT/Swift

[swift] 스위프트의 특징

1. Enum형 변수가 Associated value(연관값)를 가질수 있다.

enum Barcode {

  case upc(Int, Int, Int, Int)

  case qrCode(String)

}

 

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

 

switch productBarcode {

  case .upc(let numberSystem, let manufacturer, let product, let check):

    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")

  case .qrCode(let productCode):

    print("QR code: \(productCode).")

}

  • 위처럼 switch-case 구문에서 type 별 구분하고 저장된 연관값을 바로 접근할수 있다.

 

 

2. Switch를 간단하게 조건을 줄 수 있도록 하여 훨씬 편하고 간결하게 하였다.

let approximateCount = 62

let countedThings = "moons orbiting Saturn"

let naturalCount: String

switch approximateCount {

case 0:

  naturalCount = "no"

case 1..<5:

  naturalCount = "a few"

case 5..<12:

  naturalCount = "several"

case 12..<100:

  naturalCount = "dozens of"

case 100..<1000:

  naturalCount = "hundreds of"

default:

  naturalCount = "many"

}

print("There are \(naturalCount) \(countedThings)."

 

3. ?? 연산자 (Nil Coalesing Operator)

var anOptionalInt: Int? = 10

var anotherOptional = anOptionalInt ?? 0

 

let name: String? = nil

print("Hello, \(name ?? "Anonymous")!")

 

 

4. Switch-case나 for, while 반복 문에서 가장 안쪽 블럭에서 가장 바깥쪽 블럭을 break 할 수 있다.

gameLoop: while square != finalSquare {

  diceRoll += 1

  if diceRoll == 7 { diceRoll = 1 }

 

  switch square + diceRoll {

  case finalSquare:

      // diceRoll will move us to the final square, so the game is over

      break gameLoop

  case let newSquare where newSquare > finalSquare:

      // diceRoll will move us beyond the final square, so roll again

      continue gameLoop

  default:

      // this is a valid move, so find out its effect

      square += diceRoll

      square += board[square]

  }

}

print("Game over!")

 

5. Property를 이용하여 아래와 같이 해당 변수가 변경 되기 전, 후 불리워지는 코드를 작성할 수 있다.

var totalSteps: Int = 0 {

      willSet(newTotalSteps) {

          print("About to set totalSteps to \(newTotalSteps)")

      }

      didSet {

          if totalSteps > oldValue  {

              print("Added \(totalSteps - oldValue) steps")

          }

      }

  }

 

 

6. 프로그램 실행 시 변수값이 사용될 때, 되지 않을 때도 있는데 무조건 로딩하는 것은 자원 낭비라 이를 Swift에선 언어단에서 지원한다. Lazy property 기능을 이용하면 된다.

class DataImporter {

  /*

   DataImporter is a class to import data from an external file.

   The class is assumed to take a non-trivial amount of time to initialize.

   */

  var filename = "data.txt"

  // the DataImporter class would provide data importing functionality here

}

 

class DataManager {

  lazy var importer = DataImporter()

  var data = [String]()

  // the DataManager class would provide data management functionality here

}

 

let manager = DataManager()

manager.data.append("Some data")

manager.data.append("Some more data")

// the DataImporter instance for the importer property has not yet been created

print(manager.importer.filename)

  • 위의 코드에서 DataManager의 Importer 변수는 manager.importer.file이 호출되기 전까지는 DataImporter 클래스 생성자가 호출되지 않는다. 이런 lazy 변수를 통해서 초기 실행 속도와 메모리 가용량을 획기적으로 줄일 수 있다.

 

 

7. 함수의 리턴을 여러개 받는다.

func getTime() -> (Int, Int, Int) { ... return ( hour, minute, second) }

 

//호출

let (hour, minute, second) = getTime()

 

8. Swift에선 변수를 파라미터로 일단 넘겨주면 기본적으로 해당 변수의 변경은 불가능 하다. Reference Type으로 넘겨 주지 않는 이상 내부 값의 변경은 불가능하게 만들었다. 그래서, 변경 될 가능성이 있는 변수에 대해서는 &기호를 붙이고, Inout을 명시해서 코드를 읽어 내려갈 때 함수 호출부만 보면 변경 여부를 쉽게 알 수 있다.

func swap(inout x:Double, inout y:Doube) {

      let t = x

         x = y

         y = t

     }

  var w1 = 10, w2 = 20

     println("w1=\(w1) w2=\(w2)")

     swap(&w1,&w2)

     println("w1=\(w1) w2=\(w2)")

 

 

 

9. Swift는 Closure를 지원한다.

  • 자신이 정의되었던 문맥으로부터 모든 상수와 변수의 값을 캡쳐하거나 Refernece를 저장한다.

  • 이벤트 호출 받는 방법이 Delegate 패턴보다 더 간편하다.

// 배열 정렬하기

let numbers = [1,4,56,22,5]

 

// (함수 사용)

func sortAscending(_ i: Int, _ j: Int) -> Bool {

   return i < j

}

 

let sortedNumbers = numbers.sorted(by: sortAscending)

 

// (클로저 사용)

let sortedNumbers = numbers.sorted(by: { (i: Int, j: Int) -> Bool in

   return i < j

})

 

10. Delegate의 구현은 Protocol을 이용해서 구현하자.

C#처럼 Delegate 변수를 따로 선언해서 Assign하는 방식이 아닌, 프로토콜을 구현하여 객체를 지정하면 자동 호출이 되는 방식이다.

 

 

 

 

11. Swift는 ARC(Automatic refernce counting) 방식의 자동 GC를 지원한다. Retain Cycle만 잘 피하면, 그 외 메모리에 대한 고민을 많이 없애 주었다.

Swift가 선택한 ARC 방식은 기존 Java, C# 등에서 사용하는 GC 방식인 Cycle Collector와는 다르다. Reference Counter가 0이 되는 순간 즉시 해제 된다.

 

'IT > Swift' 카테고리의 다른 글

[swift] Protocol  (0) 2019.08.21
[swift] try? try! try  (0) 2019.08.21
[swift] ARC(Automatic Reference Counting)  (0) 2019.08.21
[swift] Closure, Capture list  (0) 2018.04.02
[swift] Mutating, Memberwise Initializers, Access Control  (0) 2018.03.13