Ch.6 옵셔널

  • 일반자료형에는 nil값을 할당할수 없음
  • 옵셔널 타입으로 선언된 자료형은 nil값을 저장할수 있음
  • nil값을 저장해야 하거나 혹은 함수나 메소드의 결과값에 nil이 포함될 가능성이 있다면(오류가 발생할 가능성이 있다면) 반환타입을 옵셔널 타입으로 설정해야함
  • 모든 일반 자료형들을 기반으로하여 각각의 자료형에 대한 옵셔널 타입이 만들어짐(클래스나 구조체포함)
  • 옵셔널 타입이 실제로 가질수 있는 값은 nil이 아닌값, nil 두가지
  • 처리에 실패시 nil값을 반환하고 성공시 옵셔널 객체로 둘러싸인 결과값을 반환
  • 결국 옵셔널 타입이란 반환하고자 하는 값을 옵셔널 객체로 다시한번 감싼 형태를 의미

6-1 옵셔널 타입 선언과 정의

  • 일반자료형을 옵셔널 타입으로 정의하는 방법
  • 자료형 뒤에 ? 붙이면 됨
  • Int?, String?
  • var optInt: Int?, var optString: String?
  • 옵셔널 타입으로 선언된 자료형을 초기화 하지 않을 경우 자동으로 nil로 초기화됨(옵셔널 타입자체에 nil이 부여된다는 뜻)
        var optInt : Int?
        optInt = 3
        print(optInt)
        
        var optStr: String?
        optStr = "Swifr"
        print(optStr)
        
        var optArr : [String]?
        optArr = ["c", "java", "objective-c","smalltalk"]
        print(optArr)

6-2 옵셔널 값 처리

  • 결과값으로 전달받은 것은 Optional이라는 객체, 그내부에 원하는 값이 들어있음.
  • 이 값을 사용하려면 실제값을 둘러싼 옵셔널객체를 해제해야함

6-2-1 명시적해제(강제해제)-Forced Unwrapping

  • 옵셔널 값의 nil여부와 관계없이 옵셔널을 무조건 해제하는 방식
  • 옵셔널 타입의 변수나 상수 뒤에 !만 붙이면 됨
  • ! 연산자만 붙이면 옵셔널 객체가 해제되고 내부에 저장된 값을 추출할 수 있음
        var optInt : Int? = 3
        print("옵셔널 자체의 값 \(optInt)")
        print("옵셔널 강제 해제의 값 \(optInt!)")
		 
		 옵셔널 자체의 값 Optional(3)
	     옵셔널 강제해제의 값 3
	
  • 강제해제 연산자를 사용할 때에는 먼저 옵셔널 값이 nil인지 점검해야함
  • 그리고 옵셔널 값이 nil이 아닐때만 강제해제 연산자를 붙여서 값을 추출해야 함
  • ! 연산자는 확실히 옵셔널의 값이 nil이 아닌 조건에서만 사용해야함

6-2-2 옵셔널 바인딩

  • 조건문 내에서 일반 상수에 옵셔널 값을 대입하는 방식으로 이루어짐
  • 반드시 조건문에서 사용해야만 하며, 상수에 옵셔널 값을 대입한 결과는 true/false로 리턴됨
        var str = "Swift"
        
        if let intFromStr = Int(str){
            print("반환된 값은\(intFromStr)입니다")
        }else {
            print("값 반환에 실패")
        }

  • 강제해제 연산자를 사용하지 않아도 옵셔널 타입의 값이 일반타입의 변수나 상수에 할당되는 과정을 거치면서 자연스럽게 옵셔널 타입이 해제되지만, 옵셔널 타입의 값이 nil일 때에는 값의 할당이 실패하여 결과값이 false로 반환될 뿐이므로 else블록이 실행되는것 이외에 오류는 발생하지 않음.
  • 딕셔너리가 옵셔널 타입의 값을 반환하는 이유는 딕셔너리에서 값을 읽을 때에는 존재하지 않는 키를 사용할 가능성이 있기때문
  • 이경우 딕셔너리는 주어진 키에 값이 비어있거나 입력된 키가 아예 없다는 것을 표현하기 위해 nil을 반환해야 함
  • 이 때문에 딕셔너리는 기본적으로 옵셔널 타입으로 정의된 값을 반환하게 됨
  • 옵셔널 타입에서 ! 연산자를 사용할 때에는 반드시 nil 점검을 해주어야 오류를 미연에 방지할 수 있음.

6-2-3 컴파일러에 의한 옵셔널 자동 해제

  • 옵셔널 객체의 값을 비교 연산자를 사용하여 비교하는 경우에 명시적으로 옵셔널 객체를 강제 해제하지 않아도 한쪽이 옵셔널, 다른 한쪽이 일반타입이라면 자동으로 옵셔널 타입을 해제하여 비교 연산을 수행
  • 비교연산을 처리할 때에는 옵셔널 타입 여부에 구애받지 않고 일반 자료형처럼 값을 비교하면 됨

6-2-4 묵시적해제

  • 옵셔널이지만 값을 사용하려고 할 때에는 자동으로 옵셔널이 해제된 값을 제공하기 때문에 굳이 ! 연산자를 사요아여 해제할 필요가 없는 구문
  • 변수의 값이 nil이 될 가능성이 있다면 묵시적 옵셔널 해제를 사용하지 않아야 함
  • 형식상 옵셔널로 정의해야 하지만 실제로 사용할 때에는 절대 nil값이 대입될 가능성이 없는 변수일때 묵시적 옵셔널 해제를 사용


블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,

Ch.13 iOS앱의 구조와 코코아 터치 프레임워크

  • 앱은 기본적으로 시스템 프레임워크에 정의된 원리에 따라 동작하지만, 이 영역을 제외한 나머지 범위에서는 커스텀 코드를 통해 원하는 기능과 유저 인터페이스를 구현할수 있음

13.1앱의 기본 구조

13.1.1 엔트리 포인트와 앱의 초기화 과정

  • Objective-C 도 C를 기반으로 하고 있기 때문에 이를 이용하여 만들어진 iOS앱도 main()함수로부터 시작됨

  • main()함수가 하는일은 실행시 시스템으로부터 전달받은 두 개의 인자값과 AppDelegate클래스를 이용하여 UIApplicationMain()함수를 호출하고 그결과로 UIApplication 객체를 반환

  • 생성된 UIApplication 객체는 UIKit 프레임 워크에 속해있으므로 이후의 앱 제어권은 UIKit 프레임워크로 이관됨

  • UIApplicationMain()함수는 iOS앱에 속하는 부분의 엔트리포인트라고 할수 있음

  • 이 함수는 앱의 핵심객체를 생성하는 프로세스를 핸들링하고, 스토리보드 파일로부터 앱의 유저 인터페이스를 읽어들일뿐만 아니라 내가 작성한 커스텀 코드를 호출해줌으로써 앱 생성 초기에 필요한 설정을 구현할 수 있게 해줌, 또한 이벤트를 입력받기 위한 이벤트 루프를 실행시키키도 함

  • UIApplicationMain()함수가 생성하는 UIApplication은 앱의 본체라고 할 수 있는 객체로 사실상 앱 그 자체를 의미함.

  • UIApplication 객체는 AppDelegate라는 대리 객체를 내세우고 커스텀 코드를 처리할 수 있도록 약간의 권한을 부여함

  • AppDelegate는 UIApplication으로부터 위임받은 일부 권한을 이용하여 커스텀 코드와 상호 작용을 하는 역할을 담당하고, 이를 통해 우리가 필요한 코드를 구현할 수 있도록 도와줌

  • AppDelegate객체는 iOS 애플리케이션 내에서 오직 하나의 인스턴스만 생성되도록 시스템 적으로 보장을 받음

    • 앱이 처음 만들어 질때 객체가 생성되고 앱이 실행되는 동안 계속 유지되다가 앱이 종료되면 그때 함께 소멸하는 등 앱 전체의 생명주기와 함께 함
  • Swift에서는 직접 UIApplicationMain()을 호출하여 delegate 클래스를 인자값으로 전달할 수 없으므로 대신 앱 델리게이트 역할을 할 클래스에 @UIApplicationMain 어노테이션을 걸어 표시하는 방식으로 시스템에 델리게이트 클래스 정보를 전달함.

  • Swift에서는 Main()함수를 통해 UIApplicationMain()을 호출하는 대신 @UIApplicationMain어노테이션을 찾아 해당 클래스를 실행
  • application(_:didFiniShingLaunchingWithOptions:)메소드에 원하는 커스텀 코드를 작성해 두면 앱이 처음 시작될때 해당 코드를 실행할 수 있음
  • 이벤트 루프가 실행되면서 내가 작성한 이벤트 핸들에 의해 커스텀 코드로 연결됨(핸들은 @IBAction등등)
  • 앱이 실행목적 완료하고 더이상 사용되지 않으면 시스템은 앱을 메모리에서 제거하기 위한 준비를 함
  • 이 과정에서 앱 시스템은 델리게이트 클래스applicationWillTerminate(_:)메소드를 호출, 앱 종료시 처리해야할 내용이 있다면 이 메소드 내부에 커스텀 코드로 작성해 두기만 하면 됨

자세한 그림 참고

*Launching an app into the foreground

*Launching an app into the background

*Handling alert-based interruptions

*Transitioning from the background to the foreground

*Moving from the foreground to the background

<[애플공식문서 참고링크] (https://goo.gl/4eEd4U)>

13.1.2 MVC패턴

  • iOS 앱의 객체 관계는 MVC패턴에 기반하고 있음
  • 모델(Model) - 데이터를 담당
  • 뷰(View) - 데이터에 대한 화면 표현을 담당
  • 컨트롤러(Controller) - 모델과 뷰 사이에 위치하여 데이터를 가공하여 뷰로 전달하고 뷰에서 발생하는 이벤트를 입력받아 처리하는 역할을 담당

  • 각각의 역할로 쪼개고 나누어 놓은 이유는 많은 장점을 가지기 때문
  • 가장 큰 장점은 앱에서 사용되는 데이터와 비즈니스 로직을 데이터에 대한 시작적인 표현으로부터 분리해 줌으로써 화면을 신경쓰지 않고도 데이터나 비즈니스 로직을 작성할 수 있다는 점

13.1.3 앱의 상태 변화

  • 앱의 상태변화는 운영체제가 처리하는 영역
  • iOS에서 앱이 가질수 있는 상태값은 다음과 같음
- Not Running : 앱이 시작되지 않았거나 실행되었지만 시스템에 의해 종료된 상태를 나타냄
- Inactive : 앱이 전면에서 실행중이지만, 아무런 이벤트를 받지 않고 있는 상태를 나타냄
- Active : 앱이 전면에서 실행중이며, 이벤트를 받고 있는 상태를 나타냄
- Background : 앱이 백그라운드에 있지만 여전히 코드가 실행되고 있는 상태를 나타냄
- Suspended : 앱이 메모리에 유지되지만 실행되는 코드가 없는 상태

  • 앱의 상태가 변화할 때마다 앱 객체는 앱 델리게이트에 정의된 특정 메소드를 호출
  • 주요 메소드는 다음과 같음
application(_:willFinishLaunchingWithOptions:)
	- 앱이 구동되어 필요한 초기실행과정이 완료되기 직전에 호출되는 메소드
application(_:didFinishLaunchingWithOptions:)
	- 앱이 사용자에게 화면으로 표시되기 직전에 호출되는 메소드
applicationDidBecomeActive(_:)
	- 실행된 앱이 포그라운드, 즉 화면 전면에 표시될때 호출되는 메소드
applicationDidEnterBackground(_:)
	- 앱이 백그라운드 상태에 진입했을때 호출
applicationWillTermainate(_:)
	- 앱이 종료되기 직전에 호출되는 메소드

UIAppdelegateProtocol 공식문서 링크

13.2 iOS와 코코아 터치 프레임 워크

13.2.1 iOS

13.2.2 코코아 터치 프레임워크

13.3 앱을 구성하는 핵심 객체들

13.3.1 iOS 유저 인터페이스의 표현구조

  • 윈도우는 iOS에서 디바이스의 스크린을 빈틈없이 채우기 위한 객체로, 항상 유저 인터페이스 표현 계층의 최상위에 위치
  • 뷰는 콘텐츠를 담아 이를 스크린상에 표시하고 사용자의 입력에 반응
  • 윈도우 객체는 항상 루트 뷰 컨트롤러만을 참조
  • 컨텐츠 뷰 컨트롤러 : 씬을 담당하고 콘텐츠를 표시하는 컨트롤러
  • 컨테이너 뷰 컨트롤러 : 콘텐츠를 배치하는 대신 다른 뷰 컨트롤러를 배치하고, 이들을 서로 유기적인 관계로 엮이도록 만들어줌

13.3.2 뷰 컨트롤러

  • 뷰 컨트롤러는 앱의 근간을 이루는 객체로 모든 앱은 최소한 하나 이상의 뷰 컨트롤러로 구성
  • View Controller : iOS 에서 가장 기본이 되는 컨트롤러로서 앱의 데이터와 표시될 외형을 연결해서 하나의 동적인 화면을 만들어 내는 컨트롤러. 내부에 뷰를 포함하고 있음 (UIKit프레임워크의 클래스는 UIViewController)
  • Navigation Controller : 앱의 화면 이동에 관한 관리와 그에 연관된 처리를 담당해주는 컨트롤러, 뷰를 포함하고 있지 않으므로 다른 컨트롤러와 결합하여 부분적으로 화면을 구성 (UIKit프레임워크의 클래스는 UINavigationController)
  • Table View Controller : 내부에 리스트 형식의 테이블 뷰를 포함하고 있어 여러 항목이나 데이터를 화면에 나열하기 위한 목적으로 사용되는 컨트롤러 (UIKit프레임워크의 클래스는 UITableViewController)
  • Tab Bar Controller : 화면을 나타내는 여러개의 탭이 있고 탭을 터치하면 화면이 전환되는 형태의 앱을 만들고자 할 때 사용되는 컨트롤러 (UIKit프레임워크의 클래스는 UITabbarController)
  • Split View Controller : (UIKit프레임워크의 클래스는 UISplitViewController)

13.3.3 뷰컨트롤러의 상태변화와 생명주기

  • 뷰컨트롤러의 생명 주기는 장면(Scene)의 전환과 복귀에 밀접하게 연관되어 있음
  • 뷰 컨트롤러는 다음과 같이 네가지 상태로 나눌수 있음
	- Appearing : 뷰 컨트롤러가 스크린에 등장하기 시작한 순간부터 등장을 완료하기 직전까지의 상태
	- Appeared : 뷰 컨트롤러가 스크린 전체에 완전히 등장한 상태
	- Disappearing : 뷰 컨트롤러가 스크린에서 가려지기 시작해서 완전히 가려지기 직전까지의 상태
	- Disappeared : 뷰 컨트롤러가 스크린에서 완전히 가려졌거나 혹은 퇴장한 상태

  • 화면이 처음 실행되거나 또는 퇴장한 상태에서 다시 등장하기 시작하는 상태(Appearing)로 바뀌는 동안 뷰 컨트롤러는 앱 객체에 의해 viewWillAppear(_:)메소드가 호출
  • 화면이 등장하기 시작한 단계를 넘어서 완전히 등장하고 나면 viewDidAppear(_:) 메소드가 호출
  • 이 상태에서 다른 액션이 일어나 화면의 전환이 이루어지거나 홈 버튼을 눌러 앱이 백그라운드로 내려가는등 스크린에서 화면이 퇴장하는 상태 변화가 발생하면 그 즉시 viewWillDisappear(_:) 메소드가 호출
  • 상태 변화가 완료 되었을때 viewDidDisappear(_:)메소드가 호출

Life Cycle


블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,
지난 포스팅에 이어서 두번째 포스팅에 들어가보겠다...

일단 소스를 보자





이번 프로그램은 객체를 2개 생성하여 각각의 인스턴스 변수및 메서드를 활용하는 것이다.
일단 클래스를 생성하여 준다. 클래스는 1편의 프로그램과 같다...
그리고 implementation부분도 생성을 해준다. 물론 이부분또한 앞과 같다..
하지만 프로그램 부분에서는 다르게 표현을 한다

Fraction 클래스의 객체를 frac1 과 frac2로 생성을 해주고 각각을 초기화 해준다..
Fraction *frac1=[[Fraction alloc]init];
Fraction *frac2=[[Fraction alloc]init]'
이부분이다. 이부분에서 각각의 객체를 생성하여주고 바로 초기화를 해준다..

다음 코드를 보면 객체하나하나에  클래스의 인스턴스변수로 숫자를 대입해 주고있다.

[frac1 setNumerator: 2];
[frac1 setDenominator::3]; 

 

frac1 의 객체에 변수들의 값을 넣어주고 

[frac2 setNumerator: 4];
[frac2 setDenominator: 5];

frac2 의 객체또한 같은 방법으로 값을 넣어준다..

그리고 객체 각각의 print메서드로 값들을 호출하게 되면 다음과 같은 결과가 나온다..



그후 객체 각각의 메모리를 반환하여 준다
[frac1 release];
[frac2 release];





다음은..인스턴스 변수의 접근과 데이터를 캡슐화 하는 코드를 보겠다..
일단 코드를 보자



객체의 인스턴스 변수에 접근하는 프로그램이다.

바로위의 프로그램과 다른것이 있다면.. 클래스선언부분에 int형 변수를 선언해놓았다.
클래스의 인스턴스 변수는 바로 접근이 불가능하다.

코드의 implementation부분에서 numerator 과 denominator을 각각 반환하는 메서드를 작성하였다.

그후 프로그램부분에서는 객체를 생성후
프린트 할때 객체의 변수값을 직접받아오는것이아니라
메서드를 거쳐 반환된 값을 출력하도록 하게 되어있다..
출력값은 상상하시는것 이상 이하도 아니다 ㅎ


 

블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,

3번째 포스팅이다..

자바할때 배웠던 클래스, 객체, 메서드에 대해서 알아보자..그러기전에 우선 예를 들고 시작해야겠다..노트북을 예로 들어보자.

노트북. 하면 여러 종류가 있다..내가 가지고 있는 맥북에어, 혹은 당신이 가지고 있는 맥북프로;;노트북의 종류는 정말 많다..

클래스란 노트북 이라고 할수 있으며맥북에어
, 맥북프로는 객체라고 설명할수 있다 즉 객체는 클래스의 하위 범주이다.클래스로
 
부터 나온것을 인스턴스라고 부르고
, 이 인스턴스가 수행하는 행동을 메서드 라고 한다.메서드는 클래스 인스턴스나 클래스
 
자체에서 적용이 되어진다
.만약 당신이 노트북(클래스)을 부셔버린다(Dell 노트북??)이는 인스턴스메서드에 해당이 된다

(클래스에 대한 행동) 하지만 노트북(클래스)을 만드는 애플, , 또시바에서 만드는 노트북의 모델을 알아내는 행동은

클래스에 적용되는 부분이므로
클래스 메서드가 된다.아 써놓고도 무슨 말인지 이해가 가지 않는다..이렇게 어려웠나 ㅠㅠ일단

내가 공부하는 책의 소스를 보면서 더 자세히 알아보자
..분수를 다루는 간단한 프로그램이다.



int형 변수 2개에 각각의 숫자를 넣어주고, 프린트로 그 넣어준 숫자를 출력하는 간단한 프로그램이다.물론 결과는 밑에 그림과 같이 나온다..





 

다음은 이 프로그램을 좀더 발전시켜 클래스를 만들어 작성해 보자..




일단 interface부분부터 살펴보자interface는 클래스, 테이터요소, 메서드를 선언한다.interface 에서 Fraction이라는 클래스를 생성하고 안에 int 형 인스턴스변수를 2개 생성하였다.

 

그리고 interface 내에서 print, setNumerator, setDenominator 메서드를 선언해 주었다setNumerator,setDenominator메서드는 모두 아무런 값도 반환하지 않고, 인수를 받는 역할을 하게 된다.

 

2번째 implementation 부분을 살펴보면interface에서 선언한 메서드들의 기능을 구현하는 부분이다.print 부분에서는 클래스의 인스턴스변수를 출력해주는 기능을setNumerator 부분에서는 클래스의 인스턴스 변수에 값을 전달해주는 기능을마찬가지로 setDenominator 부분도 클래스의 인스턴수 변수에 값을 전달해주는 부분이다.

 

자 이제 program 부분을 살펴보자 program부분에서는 클래스의 객체를 정의하는것으로 시작한다클래스 Fraction의 객체 myFraction을 정의 한다.즉 객체 myFraction이 클래스Fraction의 값을 저장한다는 말이다.

 

정의된 클래스생성 및 객체를 초기화 해주어야 하므로 myFraction = [Fraction alloc]; (클래스에 alloc메세지를 보내 그 클래스의 새로운 인스턴스를 받는다.)객체를 생성한후 초기화를 해주어야 한다.myFraction = [myFraction init]; 객체를 초기화 하였다..

 

그다음 객체를 클래스 메서드를 사용하여 각각의 값을 할당해준후 클래스메서드인 print로 할당된 값들을 출력하여 준다..그리고 객체가 사용했던 메모리를 해제해 준다..[myFractio release];

 

빌드를 하면 다음과 같은 결과가 나온다..

 




 
블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,



  Xcode 가 설치되어있는 환경이라면 위의 사진처럼 Dock에 Xcode가 나와있거나..아니면 응용프로램에 보면 위와같은 아이콘을 찾을수 있다.
이제 Xcode 아이콘을 눌러서 실행을 시키자! 그럼 밑에처럼 프로젝트 생성하는 화면이 나오게 된다.


프로젝트 선택화면 이다. 위의 선택된 Create a new Xcode project를 클릭하여 다음화면으로 넘어가자..


프로젝트를 생성하기를 누르면 이와같은 화면이 뜨게 된다.. 나는 Objective-C 공부를 할것이므로..일단 Command line tool을 선택하였다.

 



Command line tool 을 선택하고 다음을 누르면 이와같은 화면을 볼수 있는데..Product Name에는 프로젝트 이름을 써 넣는다.(아무거나..)
그 후 바로 밑에 type 에서는 foundation 을 선택하고 다음을 누르면 다음과 같은 화면을 볼수 있다..



 프로젝트를 저장할 경로를 선택하고 생성을 누른다!!

 



짜잔..이런 화면이 뜬다.. 자 이제 시작해볼까?

왼쪽에 보면 여러 폴더와 파일이 보인다..우리는 다른건 제껴두고 일단 확장자가 m 인 파일을 선택하자..



확장자가 m 인 파일. 즉 main.m 파일을 시작하면 가장 기본적인 코드가 나온다..
이제 나는 objective-c 에 발을 들여놓게 되었다....


 


#import <Foundation/Foundation.h>


int main (int argc, const char * argv[])

{


    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


    // insert code here...

    NSLog(@"Hello, World!");


    [pool drain];

    return 0;

}

가장 기본적인 소스코드 이다.
C언어와는 분명히 다른 코드들이다..이제부터 하나씩 공부해 나가자!! 
 


블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,


오늘부터 시작이다..
옛날 기억을 되살려서 고고고
블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,