iOS 개발자 가이드: Objective-C에서 Swift 학습까지
게시 됨: 2022-03-112008년에 Apple은 iPhone SDK 2.0을 발표하고 출시했습니다. 이 이벤트는 소프트웨어 개발의 또 다른 혁명을 일으켰고 새로운 유형의 개발자가 탄생했습니다. 그들은 이제 iOS 개발자로 인식됩니다.
이 개발자들 중 다수는 전에 Objective-C를 사용한 적이 없었고, 이것이 Apple이 그들에게 던진 첫 번째 도전이었습니다. 익숙하지 않은 구문과 수동 메모리 관리에도 불구하고 수만 개의 앱으로 App Store를 채우는 데 큰 성공을 거두었습니다. Apple은 각 릴리스마다 Objective-C를 지속적으로 개선하여 블록과 리터럴을 추가하고 자동 참조 카운팅을 통한 간소화된 메모리 관리 및 최신 프로그래밍 언어를 나타내는 기타 여러 기능을 개선했습니다.
그리고 6년 동안 Objective-C를 개선하고 작업한 후, Apple은 개발자들에게 또 다른 도전을 하기로 결정했습니다. 다시 한 번, iOS 개발자는 새로운 프로그래밍 언어인 Swift 를 배워야 합니다. Swift는 안전하지 않은 포인터 관리를 제거하고 강력한 새 기능을 도입하면서 Objective-C 및 C와의 상호 작용을 유지합니다.
Swift 1.0은 이미 안정적이고 강력한 개발 플랫폼이며 앞으로 몇 년 동안 흥미로운 방식으로 발전할 것입니다. 이것은 분명히 iOS 개발의 미래이기 때문에 이 새로운 언어를 탐구하기 시작하기에 완벽한 순간입니다.
이 튜토리얼의 목적은 Objective-C 개발자에게 새로운 Swift 언어 기능에 대한 간략한 개요를 제공하여 다음 단계를 수행하고 일상 업무에서 Swift를 채택할 수 있도록 돕는 것입니다. Objective-C를 설명하는 데 너무 많은 시간을 할애하지 않고 iOS 개발에 익숙하다고 가정하겠습니다.
Swift와 Objective-C 비교하기
Swift 탐색을 시작하려면 App Store에서 XCode를 다운로드하고 실험할 플레이그라운드를 만들기만 하면 됩니다. 이 기사에서 언급한 모든 예제는 이러한 방식으로 수행됩니다.
Apple의 Swift 홈페이지는 Swift 프로그래밍 학습을 위한 최고의 참고 자료입니다. 당신은 그것이 매우 귀중하다는 것을 알게 될 것이고, 당신이 Swift 개발의 속도에 완전히 익숙해질 때까지 나는 당신이 이곳에 자주 올 것이라고 믿습니다.
변수 및 상수
Swift에서 변수 선언은 var
키워드를 사용하여 수행됩니다.
var x = 1 var s = "Hello"
두 개의 변수 x
와 s
가 다른 유형임을 알 수 있습니다. x
는 정수이고 s
는 문자열입니다. Swift는 유형 안전 언어이며 할당된 값에서 변수 유형을 추론합니다. 코드를 더 읽기 쉽게 만들고 싶다면 선택적으로 변수 유형에 주석을 달 수 있습니다.
var y: Int y = 2
상수는 비슷하지만 var
대신 let
을 사용하여 선언합니다. 상수 값은 컴파일 타임에 알 필요가 없지만 정확히 한 번 값을 할당해야 합니다.
let c1 = 1 // Constant known at compile time var v = arc4random() let c2 = v // Constant known only at run time
이름에서 알 수 있듯이 변경할 수 없으므로 다음 코드에서는 컴파일 타임 오류가 발생합니다.
let c = 1 c = 3 // error
다른 유형도 상수로 선언할 수 있습니다. 예를 들어 다음 코드는 배열을 상수로 선언하고 요소를 수정하려고 하면 Swift 컴파일러에서 오류를 보고합니다.
var arr2 = [4, 5, 6] arr2[0] = 8 print (arr2) // [8, 5, 6] let arr = [1, 2, 3] a[0] = 5 // error
선택 사항
상수는 선언 시 초기화해야 하고 변수는 사용 전에 초기화해야 합니다. 그렇다면 Objective-C nil
은 어디에 있습니까? Swift는 선택적 값 을 도입합니다. 선택적 값은 값을 가질 수도 있고 nil
일 수도 있습니다. 다음 코드를 살펴보면 x
에 Optional
값 2014
가 할당되었음을 알 수 있습니다. 이것은 스위프트 컴파일러가 x
도 nil
일 수 있다는 것을 인식했음을 의미합니다.
var s = "2014" var x = s.toInt() print(x) // Optional(2014)
이 코드를 변경하고 Integer로 변환할 수 없는 값 "abc"
를 s
에 할당하면 x
가 이제 nil
임을 알 수 있습니다.
var s = "abc" var x = s.toInt() print(x) // nil
toInt()
함수의 반환 유형은 Int?
, 선택적 Int 입니다. x
에서 표준 함수를 호출해 보겠습니다.
var x = "2014".toInt() print(x.successor()) // error
x
는 선택 사항이고 잠재적으로 nil일 수 있기 때문에 컴파일러는 오류 신호를 보냅니다. 먼저 x
를 테스트하고 successor
함수가 nil
값이 아닌 실수에 대해 호출되는지 확인해야 합니다.
var x = "2014".toInt() if x != nil { print(x!.successor()) // 2015 }
느낌표(!)를 추가하여 x
를 풀어야 합니다. x
에 값이 포함되어 있다고 확신하면 해당 값에 액세스할 수 있습니다. 그렇지 않으면 런타임 오류가 발생합니다. 우리는 또한 Swift가 optional binding 이라고 부르는 것을 할 수 있습니다. optional을 non-optional 변수로 변환합니다.
let x = "123".toInt() if let y = x { print(y) }
if
문의 코드는 x
에 값이 있는 경우에만 실행되고 이를 y
에 할당합니다. 우리는 y
를 unwrap할 필요가 없습니다. x
가 nil
이 아니라는 것을 알기 때문에 type은 선택 사항이 아닙니다.
선택적 연결과 같은 멋진 기능과 선택 사항에 대한 자세한 내용을 보려면 Apple의 Swift 자습서를 확인하세요.
문자열 보간
Objective-C에서 문자열 형식화는 일반적으로 stringWithFormat:
메소드를 사용하여 수행됩니다.
NSString *user = @"Gabriel"; int days = 3; NSString *s = [NSString stringWithFormat:@"posted by %@ (%d days ago)", user, days];
Swift에는 동일한 작업을 수행하는 문자열 보간 이라는 기능이 있지만 더 간결하고 읽기 쉽습니다.
let user = "Gabriel" let days = 3 let s = "posted by \(user) \(days) ago"
다음과 같은 표현식을 사용할 수도 있습니다.
let width = 2 let height = 3 let s = "Area for square with sides \(width) and \(height) is \(width*height)"
Swift의 문자열 보간 및 기타 새로운 기능에 대해 자세히 알아보려면 여기로 이동하십시오.
기능
Swift의 함수 정의는 C와 다릅니다. 샘플 함수 정의는 다음과 같습니다.
func someFunction(s:String, i: Int) -> Bool { ... // code }
Swift 함수는 일급 유형 입니다. 즉, 변수에 함수를 할당하거나, 다른 함수에 매개변수로 전달하거나, 반환 유형을 만들 수 있습니다.
func stringLength(s:String) -> Int { return countElements(s) } func stringValue(s:String) -> Int { if let x = s.toInt() { return x } return 0 } func doSomething(f:String -> Int, s:String) -> Int { return f(s).successor() } let f1 = stringLength let f2 = stringValue doSomething(f1, "123") // 4 doSomething(f2, "123") // 124
다시 말하지만, Swift는 f1
및 f2
( String
-> Int
) 유형을 유추하지만 명시적으로 정의할 수 있습니다.
let f1:String -> Int = stringLength
함수는 다른 함수를 반환할 수도 있습니다.
func compareGreaterThan(a: Int, b: Int) -> Bool { return a > b } func compareLessThan(a: Int, b: Int) -> Bool { return a < b } func comparator(greaterThan:Bool) -> (Int, Int) -> Bool { if greaterThan { return compareGreaterThan } else { return compareLessThan } } let f = comparator(true) println(f(5, 9))
Swift의 기능에 대한 가이드는 여기에서 찾을 수 있습니다.
열거
Swift의 열거형은 Objective-C보다 훨씬 강력합니다. Swift 구조체는 메서드를 가질 수 있으며 값으로 전달됩니다.
enum MobileDevice : String { case iPhone = "iPhone", Andro, WP8 = "Windows Phone8", BB = "BlackBerry" func name() -> String { return self.toRaw() } } let m = MobileDevice.Android print(m.name()) // "Android"
Objective-C와 달리 Swift 열거형은 정수 외에 문자열, 문자 또는 부동 소수점을 각 멤버에 대한 값으로 할당할 수 있습니다. 편리한 toRaw()
메서드는 각 멤버에 할당된 값을 반환합니다.
열거형도 매개변수화할 수 있습니다.
enum Location { case Address(street:String, city:String) case LatLon(lat:Float, lon:Float) func description() -> String { switch self { case let .Address(street, city): return street + ", " + city case let .LatLon(lat, lon): return "(\(lat), \(lon))" } } } let loc1 = Location.Address(street: "2070 Fell St", city: "San Francisco") let loc2 = Location.LatLon(lat: 23.117, lon: 45.899) print(loc1.description()) // "2070 Fell St, San Francisco" print(loc2.description()) // "(23.117, 45.988)"
열거형에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

튜플
튜플은 여러 값을 단일 복합 값으로 그룹화합니다. 튜플 내의 값은 모든 유형이 될 수 있으며 서로 동일한 유형일 필요는 없습니다.
let person = ("Gabriel", "Kirkpatrick") print(person.0) // Gabriel
개별 튜플 요소의 이름을 지정할 수도 있습니다.
let person = (first: "Gabriel", last: "Kirkpatrick") print(person.first)
튜플은 둘 이상의 값을 반환해야 하는 함수의 반환 유형으로 매우 편리합니다.
func intDivision(a: Int, b: Int) -> (quotient: Int, remainder: Int) { return (a/b, a%b) } print(intDivision(11, 3)) // (3, 2) let result = intDivision(15, 4) print(result.remainder) // 3
Objective-C와 달리 Swift는 switch 문에서 패턴 일치를 지원합니다.
let complex = (2.0, 1.1) // real and imaginary parts switch complex { case (0, 0): println("Number is zero") case (_, 0): println("Number is real") default: println("Number is imaginary") }
두 번째 경우에는 숫자의 실수 부분을 신경 쓰지 않으므로 _
를 사용하여 일치시킵니다. 각 경우에 추가 조건을 확인할 수도 있습니다. 이를 위해 패턴 값을 상수에 바인딩해야 합니다.
let complex = (2.0, 1.1) switch complex { case (0, 0): println("Number is zero") case (let a, 0) where a > 0: println("Number is real and positive") case (let a, 0) where a < 0: println("Number is real and negative") case (0, let b) where b != 0: println("Number has only imaginary part") case let (a, b): println("Number is imaginary with distance \(a*a + b*b)") }
비교 또는 case 문에서 사용할 값만 바인딩해야 하는 방법에 유의하십시오.
튜플에 대한 자세한 내용을 보려면 여기로 이동하십시오.
클래스 및 구조
Objective-C와 달리 Swift는 사용자 정의 클래스 및 구조에 대해 별도의 인터페이스 및 구현 파일을 만들 필요가 없습니다. Swift를 배우면서 단일 파일에서 클래스 또는 구조를 정의하는 방법을 배우게 되며 해당 클래스 또는 구조에 대한 외부 인터페이스는 자동으로 다른 코드에서 사용할 수 있게 됩니다.
클래스 정의
클래스 정의는 매우 간단합니다.
class Bottle { var volume: Int = 1000 func description() -> String { return "This bottle has \(volume) ml" } } let b = Bottle() print(b.description())
보시다시피 선언과 구현은 같은 파일에 있습니다. Swift는 더 이상 헤더 및 구현 파일을 사용하지 않습니다. 예제에 레이블을 추가해 보겠습니다.
class Bottle { var volume: Int = 1000 var label:String func description() -> String { return "This bottle of \(label) has \(volume) ml" } }
레이블은 선택 사항이 아닌 변수이고 Bottle이 인스턴스화될 때 값을 보유하지 않기 때문에 컴파일러는 불평할 것입니다. 초기화 프로그램을 추가해야 합니다.
class Bottle { var volume: Int = 1000 var label:String init(label:String) { self.label = label } func description() -> String { return "This bottle of \(label) has \(volume) ml" } }
또는 초기화되지 않는 속성에 대해 Optional
유형을 사용할 수 있습니다. 다음 예에서 우리는 volume
을 Optional Integer
로 만들었습니다.
class Bottle { var volume: Int? var label:String init(label:String) { self.label = label } func description() -> String { if self.volume != nil { return "This bottle of \(label) has \(volume!) ml" } else { return "A bootle of \(label)" } } }
구조
Swift 언어에도 structs
가 있지만 Objective-C보다 훨씬 유연합니다. 다음 코드 자습서에서는 struct
를 정의합니다.
struct Seat { var row: Int var letter:String init (row: Int, letter:String) { self.row = row self.letter = letter } func description() -> String { return "\(row)-\(letter)" } }
Swift의 클래스와 마찬가지로 구조에는 메서드, 속성, 초기화 프로그램이 있으며 프로토콜을 준수할 수 있습니다. 클래스와 구조체의 주요 차이점은 클래스 는 참조로 전달되는 반면 구조체는 값으로 전달된다는 것입니다 .
이 예에서는 참조로 클래스를 전달하는 방법을 보여줍니다.
let b = Bottle() print(b.description()) // "b" bottle has 1000 ml var b2 = b b.volume = 750 print(b2.description()) // "b" and "b2" bottles have 750 ml
struct
와 비슷한 경우를 시도하면 변수가 값으로 전달된다는 것을 알 수 있습니다.
var s1 = Seat(row: 14, letter:"A") var s2 = s1 s1.letter = "B" print(s1.description()) // 14-B print(s2.description()) // 14-A
언제 struct
를 사용해야 하고 언제 class
를 사용해야 합니까? Objective-C 및 C에서와 같이 몇 가지 값을 그룹화해야 할 때 구조체를 사용하고 참조가 아니라 복사될 것으로 예상합니다. 예를 들어, 복소수, 2D 또는 3D 점 또는 RGB 색상입니다.
클래스의 인스턴스는 전통적으로 객체로 알려져 있습니다. 그러나 Swift 클래스와 구조는 다른 언어보다 기능면에서 훨씬 더 가깝고 많은 기능을 클래스 또는 구조 유형의 인스턴스에 적용할 수 있습니다. 이 때문에 Swift 참조에서 사용되는 보다 일반적인 용어는 이 두 가지 중 하나에 적용되는 instance
입니다.
여기에서 Swift 클래스 및 구조의 기본 사항을 배우십시오.
속성
앞에서 보았듯이 Swift의 속성은 클래스 또는 구조체 정의 내에서 var
키워드로 선언됩니다. let
문으로 상수를 선언할 수도 있습니다.
struct FixedPointNumber { var digits: Int let decimals: Int } var n = FixedPointNumber(digits: 12345, decimals: 2) n.digits = 4567 // ok n.decimals = 3 // error, decimals is a constant
또한 클래스 속성에 weak
키워드를 접두사로 붙이지 않는 한 클래스 속성은 강력하게 참조됩니다. 그러나 선택적이 아닌 약한 속성에는 약간의 미묘함이 있으므로 Apple의 Swift 가이드에서 자동 참조 계산 장을 읽으십시오.
계산된 속성
계산된 속성은 실제로 값을 저장하지 않습니다. 대신 다른 속성과 값을 간접적으로 검색하고 설정할 수 있는 getter 및 선택적 setter를 제공합니다.
다음 코드는 계산된 값 sign
의 샘플을 제공합니다.
enum Sign { case Positive case Negative } struct SomeNumber { var number:Int var sign:Sign { get { if number < 0 { return Sign.Negative } else { return Sign.Positive } } set (newSign) { if (newSign == Sign.Negative) { self.number = -abs(self.number) } else { self.number = abs(self.number) } } } }
getter를 구현하여 읽기 전용 속성을 정의할 수도 있습니다.
struct SomeNumber { var number:Int var isEven:Bool { get { return number % 2 == 0 } } }
Objective-C에서 속성은 일반적으로 인스턴스 변수에 의해 뒷받침되며 명시적으로 선언되거나 컴파일러에서 자동으로 생성됩니다. 반면에 Swift에서는 속성에 해당 인스턴스 변수가 없습니다 . 즉, 속성의 백업 저장소에 직접 액세스할 수 없습니다. Objective-C에 이것을 가지고 있다고 가정합니다.
// .h @interface OnlyInitialString : NSObject @property(strong) NSString *string; @end // .m @implementation OnlyInitialString - (void)setString:(NSString *newString) { if (newString.length > 0) { _string = [newString substringToIndex:1]; } else { _string = @""; } } @end
Swift에서 계산된 속성에는 백업 저장소가 없으므로 다음과 같이 해야 합니다.
class OnlyInitialString { var initial:String = "" var string:String { set (newString) { if countElements(newString) > 0 { self.initial = newString.substringToIndex(advance(newString.startIndex, 1)) } else { self.initial = "" } } get { return self.initial } } }
속성은 여기에 더 자세히 설명되어 있습니다.
계속
Generics, Objective-C 라이브러리와의 상호 작용, 클로저, 선택적 체이닝, 연산자 오버로딩과 같이 Swift에서 배워야 할 더 중요한 새로운 것들이 많이 있습니다. 하나의 튜토리얼로 새로운 언어를 완전히 설명할 수는 없지만 Swift 프로그래밍 학습에 대해 훨씬 더 많이 쓰여질 것이라는 데에는 의심의 여지가 없습니다. 그러나 이 빠른 읽기 가 시간을 내고 Swift 언어에 대한 세부 정보를 배우지 못한 많은 Objective-C 개발자가 올바른 방향으로 나아가고 Swift 새가 새로운 차원으로 데려가도록 하는 데 도움이 될 것이라고 믿습니다.