ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Apple Dev Reference] 앱 라이프사이클 The App Life Cycle
    앱등이에게 살충제를 뿌린다./Apple Dev Reference 2016. 1. 10. 18:44


    Apple Developer 문서를 번역만 하였습니다.

    The App Life Cycle

    앱은 여러분이 작성한 코드와 시스템 프레임워크간의 상호작용의 결과물이라고 볼 수 있습니다. 프레임워크에서는 앱의 실행에 필요한 환경에 필요한 도구를 제공하고 또한 여러분이 원하는 느낌의 앱을 만들 수 있는 도구를 제공합니다. 이러한 프레임워크를 효과적으로 사용하기 위해서 iOS Infra structure에 대한 간단한 이해가 필요합니다. 


    iOS Framework는 MVC와 Delegation이라는 디자인패턴에 의존하고 있습니다. 완성도있는 앱을 제작하는데에 있어서 이러한 디자인패턴을 이해하는것은 매우 중요합니다. Objective-C언어와 이 언어에 대한 특징을 이해하는 것도 매우 도움이 됩니다. 만약 iOS프로그래밍이 처음이시라면 Start Devloping iOS Apps Today를 통해 iOS와 Objective-C에 대한 소개를 보시길 권합니다.




    The Main Function

    모든 C언어 기반의 프로그램의 시작점은 main 함수입니다. iOS앱도 예외는 아닙니다. 작은 차이가 있다면 iOS앱에서는 여러분이 직접 main 함수를 작성하지 않는다는 것입니다. 여러분 대신 XCode에서 여러분의 프로젝트에 main 함수를 생성해 줍니다. 아래는 main 함수에 대한 예제입니다. 특별한 예외 상황이 아니라면 XCode가 제공하는 이 main 함수를 함부로 변경하지 않으시는게 좋습니다.


    #import <UIKit/UIKit.h>
    #import "AppDelegate.h"
     
    int main(int argc, char * argv[])
    {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }

    The only thing to mention about the main function is that its job is to hand control off to the UIKit framework. 

    UIApplicationMain 함수는 여러분의 앱에 몇가지 중요한 객체를 생성하고 스토리보드에서 UI를 로딩하고 앱의 초기 셋팅값(info.plist)을 불러오고 앱을 Run loop에 올려 놓으며 함수를 진행시킵니다. 여러분이 넘겨주는 값은 스토리보드파일과 앱 초기셋팅 정보 뿐입니다.




    The Structure of an App

    앱이 시작되면서 UIApplicationMain 함수는 몇가지 중요한 객체를 생성하고 앱을 실행시킵니다. 모든 iOS앱의 중심에는 시스템과 앱의 여러 객체들간의 대화를 가능하게 해주는 UIApplication 객체가 있습니다. 아래 그림은 대부분의 앱에서 공통으로 사용되는 객체를 보여주고 있고 표에서는 그 객체들의 역할에 대해서 설명하고 있습니다.

    가장 먼저 아셔야할 점은 iOS앱은 Model-view-controller구조를 사용한다는 것입니다. 이 디자인패턴은 앱의 Data와 비지니스 로직을 UI요소로부터 분리를 시켜줍니다. 이 패턴 덕분에 서로다른 사이즈의 디바이스에서도 앱의 동작이 가능합니다.






    Object

    Description 

    UIApplication 객체

    UIApplication객체는 Event loop를 관리합니다. 또한 델리게이트(여러분이 정의한 커스텀 객체)에 앱 상태변화나 푸쉬알림같은 주요한 이벤트등을 알려줍니다. 현재로서는 서브클래싱을 하지말고 그냥 사용하시길 권장합니다.

    App Delegate 객체 

     여러분이 작성한 코드의 핵심은 delegate입니다. 이 객체는 UIApplication객체와 함께 앱 초기화, 앱 상태변화, 많은 high-level 이벤트등을 관리합니다. 이 객체는 앱당 하나만 존재할 수 있도록 보장되기 때문에, 앱의 초기 자료구조를 설정하는데 주로 사용됩니다.

    Documents and data model 객체

     Data model objects는 앱의 콘텐츠를 저장하는데 사용되고 각 앱에 대한 고유성을 가집니다. 예를 들어, 뱅킹앱은 financial transaction에 대한 데이터베이스를 저장할 수도 있고, 그림그리는 앱은 이미지는 이미지 객체를 저장하거나 심지어 그 이미지를 생성하기 위한 명령 Sequence를 저장할 수 있습니다. 


    앱에서는 앱의 Data model objects의 데이터의 일부를 관리하기 위해 document objects(UIDocument의 서브클래스)를 사용할 수 있습니다. Document 객체는 필수는 아니지만 파일에 저장된 그룹데이터를 다루는데에 편리한 기능을 제공합니다. 


    Documents에 대해 자세히 알아보시려면 Document-Based App Programming Guide for iOS를 살펴보세요.

     View Controller 객체

    View controller 객체는 앱의 내용을 화면에 나타내는 기능을 합니다. 하나의 View Controller는 하나의 뷰와 이 뷰의 subview들을 관리합니다. 화면에 뷰가 표시될 때 view controller객체는 뷰들을 앱의 window에 설치함으로써 보여지게 해줍니다.


    UIViewController 클래스는 모든 view controller객체의 부모클래스입니다. 이 클래스는 뷰를 로드하고, 나타내고, 디바이스의 회전에 따라 또 돌려주고, 또 여러 기본 동작에 대한 기능을 제공하고 있습니다. UIKit과 또 다른 프레임워크에서 추가적으로 다른 view controller를 제공하고 있습니다. Image picker, tab bar interface, navigation interface와도 같은 것들 말입니다.


    View Controllers사용에 대해 자세히 알아보시려면 View Controller Programming Guide for iOS를 살펴보세요.

     UIWindow 객체

     UIWindow 객체는 화면에 나타날 뷰들을 다룹니다. 대부분의 앱들은 Main screen에 해당하는 Window 딱 한개만 가집니다. 외부 디스플레이를 지원하기 위한 추가적인 window를 가질수도 있습니다. 


    앱 컨텐츠를 변경하시려면 view controller를 사용하여 변경하시기 바랍니다. 절대로 window를 변경하시면 안됩니다.


    뷰를 보여주는 역할 외에도, window는 UIApplication객체와 같이 작동하여 view controller와 view에게 이벤트를 전달하는 역할을 합니다.

     View 객체, control 객체, layer객체

     View와 Control은 앱 컨텐츠 중 시각적인 부분을 제공합니다. View는 지정된 사각형(frame)의 공간에 내용물을 그리고 그 프레임 안의 이벤트에 응답하는 객체입니다. Control은 Button, Text field, toggl switch와 같은 특정한 역할을 담당하는 View를 말합니다. 


    UIKit Framework는 다양한 종류의 콘텐츠에 해당하는 기본 뷰들을 제공하고 있습니다. UIView또는 UIView의 서브클래스(Button, Label 등)를 상속받아 커스텀 뷰를 작성할 수도 있습니다. 


    앱은 이런 view와 control을 포함하는 일 외에도, Core Animation layer를 view와 control의 계층에 포함시킬 수 있습니다. Layer 객체는 사실 시각적 요소에 대한 Data객체입니다. View는 Scene의 뒷부분에서 이 layer객체를 사용하여 컨텐츠내용을 나타냅니다. 애니메이션이나 다른 시각적 효과를 보여주기 위해서 커스텀 layer객체를 만들어 사용하실 수 있습니다.


    하나의 iOS앱은 앱이 관리하는 데이터 내용과, 이 데이터를 표시하는 방법을 통해 다른 앱과의 차별점을 갖게 됩니다.

    UIKit 객체들간의 동작만으로 여러분의 앱을 작동시킬 수는 없지만 그 작동에 많은 도움이 됩니다. 예를 들어 여러분의 app delegate메소드는 앱의 상태변화를 체크하여 여러분에게 적절한 처리를 할 수 있도록 알려주는 역할을 합니다.





    The Main Run Loop

    한 앱의 Main Run Loop는 사용자와 관련된 프로세스들을 처리합니다. UIApplication 객체는 앱이 실행(launch)되는 시점에 메인 run loop를 생성한 뒤 이 run loop로 이벤트를 처리합니다. 이름에서 풍기듯이, Main run loop는 앱의 메인 스레드에서 동작합니다. main run loop는 사용자 관련 이벤트들을 받은 순서대로 처리합니다.


    아래 그림은 앱에서의 main run loop와 사용자의 이벤트가 어떻게 인식되는지에 대한 구조를 보여줍니다. 사용자가 디바이스에서 특정 액션을 취하면, 그 액션에 해당하는 이벤트가 시스템에 의해 생성되어 UIKit에서 생성한 port를 통해 앱에 전달됩니다. 이벤트들은 앱 내부적으로 큐에 저장된 채 차례대로 해당 동작이 실행되게 됩니다. UIApplication객체가 가장 먼저 이 이벤트를 받아서 어떤 동작이 취해질 지 결정합니다. 터치 이벤트의 경우 main window 객체가 인식하고 window 객체가 다시 터치가 발생한 view로 이벤트를 전달합니다. 다른 이벤트들도 다양한 app 객체들에 따라 조금씩 다르게 작동합니다.



    iOS앱 내부에서는 정말 다양한 이벤트들이 전달됩니다. 아래 표에는 가장 많이 발생하는 이벤트들에 대한 설명이 되어있습니다. 대부분 Main run loop를 통해 전달되지만 아닌 이벤트들도 있습니다. 몇몇 이벤트는 delegate 객체로 전달되거나 여러분이 전달하는 Block을 통해 전달되기도 합니다. Touch, Remote Control, Motion, Accelerometer, Gyroscopic 등의 이벤트를 포함한 여러 이벤트들에 대한 정보는 Event Handling Guide for iOS를 살펴보세요.


    이벤트 종류

    이벤트가 전달될 곳

    설명 

     Touch

    터치 이벤트가 발생한 view 객체 

    View는 응답을 할 줄 아는 객체입니다. 해당 뷰에서 처리되지 않는 터치이벤트는 Responder chain을 따라 계속 내려가게 됩니다. 

     Remote control

    Shake motion events

    최초 Responder 객체

    Remote Control이벤트는 주로 헤드폰과 같은 액세서리에서 발생합니다. 미디어의 되감기 등 

     Accelerometer

    Magnetometer

    Gyroscope

    여러분이 직접 지정한 객체 

    가속도, 방향(magnetometer), 중력센서와 관련된 이벤트는 여러분이 지정한 객체로 전달됩니다. 

     Location

    여러분이 직접 지정한 객체  

    Core Location Framework를 사용하여 사용하여 위치와 관련된 이벤트를 등록할 수 있습니다. Core Location에 대한 정보는 Location and Maps Programming Guide를 살펴보세요. 

     Redraw

    업데이트가 필요한 객체

    Redraw이벤트는 이벤트 객체를 갖지는 않습니다. 단순히 업데이트가 필요한 view객체에 요청을 합니다. Drawing architecture for iOS를 통해 자세히 살펴볼 수 있습니다. 



    touch, remote control과 같은 이벤트는 앱의 Responder 객체를 통해 처리됩니다. Responder 객체는 앱의 모든 곳에 존재합니다.(UIApplication객체, 여러분이 만든 view객체, view controller객체 모두 Responder객체에 해당합니다.)  대부분의 이벤트는 특정 객체를 대상으로 전달되지만 다른 객체로 변경할 수도 있습니다.(UIView의  hitTest나 pointInside사용 등) 예를 들어, 이벤트를 받은 객체에서 해당 이벤트를 처리하지 않는다면 부모뷰로 이벤트를 전달시킬 수 있습니다.


    Control(ex.Button)에서 발생하는 터치이벤트는 다른 view의 이벤트 전달 방식과 조금 다르게 동작합니다. Control에는 보통 몇 가지 지정된 이벤트가 존재합니다. 그 이벤트들을 다시 Action 메시지로 패키징하여 지정된 객체로 전달됩니다. 이 Target-action 디자인 패턴이 특정 액션이 여러분이 작성한 코드로 연결되는 작업을 쉽게 해주는 패턴입니다.





    Execution States for Apps

    앱은 항상 아래 테이블에 있는 상태중 하나의 상태를 가집니다. 시스템 내에서 일어나는 액션들을 통해 시스템은 앱의 상태를 바꾸게 됩니다. 예를 들어 사용자가 홈버튼을 누르거나, 전화가 오거나, 다른 어떤 인터럽트의 발생으로 인해 현재 실행중인 앱은 상태를 바꾸게 됩니다.



     State

     Description

     Not running

    아직 실행되지 않았거나 실행되다가 시스템에 의해 종료된 상태 

     Inactive

    앱이 Foreground에 올라와 있지만 이벤트를 받지 않고 있는 상태(다른 코드를 실행 중일 수도 있다.). 

    앱에서는 보통 앱 상태변화가 일어나는 동안에 짧게 이 상태를 갖게됩니다. 

     Active 

    앱이 Foreground에서 실행중이고 이벤트를 받고 있는 상태. Foreground에 올라와 있는 앱은 대부분 이 상태를 갖고있습니다. 

     Background

    앱이 Background에 있고 코드를 실행하고 있는 상태. 대부분의 앱은 Suspended상태로 가는 도중에 잠깐 이 상태를 갖게됩니다. Background상태에서 추가적인 코드수행시간이 필요햔 앱일 경우에는 좀 더 머무를수도 있습니다. 외에도 Background상태로 실행이 되는 앱의 경우에는 Inactive상태 대신 Background상태로 진입합니다. Background에서의 코드실행은 Background Execution을 살펴보세요.

     Suspended

    앱이 Background에 있으면서 코드를 수행하고 있지 않는 상태. 시스템은 자동으로 Suspended상태로 변경합니다. 그리고 변경할 때 따로 알려주지는 않습니다. Suspended되어 있는 동안 앱은 메모리상에는 올라가 있지만 어떤 코드도 실행시키지 않습니다.

    메모리가 부족한 상황에서 시스템은 현재 앱의 원활한 동작을 위해 앱을 죽이기도 합니다. 이 때도 따로 알려주지는 않습니다.





    대부분의 상태변화는 AppDelegate객체의 메소드 호출을 거쳐갑니다. 아래의 메소드들은 앱의 각 상태변화에 따라 적절한 처리를 할 수 있게 해줍니다.



    App Termination

    앱은 언제든지 종료될 수 있기 때문에 항상 앱 종료에 대한 대비를 하여 사용자 데이터를 저장하거나 크리티컬한 작업을 수행할 수 있어야 합니다. 시스템에서 앱을 종료시키는 건 앱의 Life Cycle에 따라 아주 자연스러운 부분입니다. 시스템은 주로 다른 앱을 위한 메모리 확보를 위해 앱을 종료시키게 됩니다. 하지만 시스템은 앱의 오작동이나 이벤트에 적절한 대처가 없을 경우에도 종료를 시키게 됩니다.


    Suspended상태의 앱은 앱이 종료될 때(시스템이 프로세스를 kill하고 메모리를 확보하기 위함) 어떤 알림도 받지 못합니다. 하지만 만약 앱이 Background에서 돌아가고 있어 Suspended상태가 아니라면 시스템은 앱을 종료시키기 전에 applicationWillTerminate:메소드를 호출하게 됩니다. 디바이스를 재부팅할 때는 이 메소드를 호출하지 않습니다.


    시스템이 앱을 종료시키는 것 외에도, 사용자가 Multitasking UI를 사용하여 앱을 종료시킬 수 있습니다. 사용자가 앱을 종료시킬 때는 Suspended 상태의 앱을 종료시키는 것과 같은 효과를 갖게 됩니다. 앱은 죽게되고 앱 종료에 대한 알림은 전달되지 않습니다.




    Threads and Concurrency

    시스템은 앱의 메인 스레드를 만듭니다. 여러분 또한 여러 작업을 수행하기 위해 필요한만큼 추가적인 스레드를 생성할 수 있습니다. iOS에서 멀티스레드를 위해 주로 사용하는 방법은 GCD(Grand Central Dispatch), Operation Objects, 비동기 programming interfaces입니다. 개발자가 직접 스레드를 생성하여 관리하는 것은 지양하고 있습니다. GCD와 같은 기술은 여러분이 수행하고자 하는 작업을 원하는 순서대로 정의할 수 있는 방법을 제공합니다. 동시에 시스템에게 사용가능한 CPU자원으로 최선의 작업수행을 하는 방법을 선택하도록 합니다. 시스템에게 이러한 스레드 관리를 맡김으로써 여러분이 작성해야할 코드는 더욱 간결해지게 됩니다.


    Threads and Concurrency를 고려할 때 아래를 참고하세요.

    • View와 관련된 작업, Core Animation, 그리고 다양한 UIKit클래스들에 대한 작업은 무조건 앱의 Main 스레드에서 이루어져야 합니다. 예외도 있긴합니다. 예를 들어 이미지에 기반한 작업은 Background 스레드에서 수행될 수 있습니다. 하지만 조금이라도 의심이 가신다면 그냥 Main 스레드에서 작업을 하는걸로 생각하시면 됩니다.
    • 규모가 큰 작업(또는 길어질 수도 있는 작업)은 Background 스레드에서 진행해야 합니다. 네트워크 접근, 파일 접근, 대용량 데이터들에 대한 처리등을 포함하는 작업은 GCD 또는 Operation객체를 통해 Background 스레드에서 이루어지도록 해야합니다.
    • 앱 실행시에는 가능한한 많은 작업들을 Main 스레드에서 빼주세요. 앱이 런치되는 시간에 앱은 최대한 빨리 UI를 셋팅하는데 집중해야 합니다. 따라서 앱의 UI셋팅에 필요한 작업들만 Main 스레드에 포함시키도록 해야 합니다. 다른 작업들은 비동기로 수행되어 완료가 되는 시점에 사용자에게 보여지도록 하는 방법을 사용해야 합니다.
    GCD와 Operation 객체를 사용하여 작업을 처리하는 방식은 Concurrency Programming Guiide를 참고하세요.



    출처 : https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html


Designed by Tistory.