CLIEN

본문 바로가기 메뉴 바로가기 보기설정 테마설정
톺아보기 공감글
커뮤니티 커뮤니티전체 C 모두의광장 F 모두의공원 I 사진게시판 Q 아무거나질문 D 정보와자료 N 새로운소식 T 유용한사이트 P 자료실 E 강좌/사용기 L 팁과강좌 U 사용기 · 체험단사용기 W 사고팔고 J 알뜰구매 S 회원중고장터 B 직접홍보 · 보험상담실 H 클리앙홈
소모임 소모임전체 ·굴러간당 ·아이포니앙 ·주식한당 ·MaClien ·일본산당 ·방탄소년당 ·개발한당 ·자전거당 ·AI당 ·이륜차당 ·안드로메당 ·콘솔한당 ·소시당 ·키보드당 ·PC튜닝한당 ·테니스친당 ·육아당 ·갖고다닌당 ·소셜게임한당 ·노젓는당 ·골프당 ·위스키당 ·VR당 ·창업한당 ·나혼자산당 ·나스당 ·바다건너당 ·클다방 ·IoT당 ·어학당 ·여행을떠난당 ·디아블로당 ·라즈베리파이당 ·달린당 ·냐옹이당 ·레고당 ·3D메이킹 ·X세대당 ·ADHD당 ·AI그림당 ·날아간당 ·사과시계당 ·배드민턴당 ·야구당 ·농구당 ·블랙베리당 ·곰돌이당 ·비어있당 ·FM당구당 ·블록체인당 ·보드게임당 ·활자중독당 ·볼링친당 ·캠핑간당 ·문명하셨당 ·클래시앙 ·요리한당 ·쿠키런당 ·대구당 ·DANGER당 ·뚝딱뚝당 ·개판이당 ·동숲한당 ·날아올랑 ·전기자전거당 ·e북본당 ·이브한당 ·패셔니앙 ·물고기당 ·도시어부당 ·FM한당 ·맛있겠당 ·포뮬러당 ·젬워한당 ·걸그룹당 ·안경쓴당 ·차턴당 ·총쏜당 ·땀흘린당 ·하스스톤한당 ·히어로즈한당 ·인스타한당 ·KARA당 ·꼬들한당 ·덕질한당 ·가죽당 ·리눅서당 ·LOLien ·Mabinogien ·임시소모임 ·미드당 ·밀리터리당 ·땅판당 ·헌팅한당 ·오른당 ·영화본당 ·MTG한당 ·소리당 ·노키앙 ·적는당 ·방송한당 ·찰칵찍당 ·그림그린당 ·소풍간당 ·심는당 ·패스오브엑자일당 ·품앱이당 ·리듬탄당 ·Sea마당 ·SimSim하당 ·심야식당 ·윈태블릿당 ·미끄러진당 ·축구당 ·스타한당 ·스팀한당 ·파도탄당 ·퐁당퐁당 ·테스트당 ·빨콩이당 ·공대시계당 ·터치패드당 ·트윗당 ·가상화폐당 ·시계찬당 ·WebOs당 ·와인마신당 ·WOW당 ·윈폰이당
임시소모임
고객지원
  • 게시물 삭제 요청
  • 불법촬영물등 신고
  • 쪽지 신고
  • 닉네임 신고
  • 제보 및 기타 제안
© CLIEN.NET
공지[점검] 잠시후 서비스 점검을 위해 약 30분간 접속이 차단됩니다. (금일 18:15 ~ 18:45)

개발한당

[iOS] ViewController에서 loadView, viewDidLoad, viewDidUnload는? 3

2010-11-22 23:09:11 121.♡.66.141
ebizboy

 

ViewController에서 몇가지 얘기해 보려합니다.

 

일단 링크에 보신 공식문서에 설명은 아주 잘 나와있습니다;

 

UIViewController에서

 

뷰를 로드할 때 쓰는 것이

 

- (void)loadView

- (void)viewDidLoad

지요... 그리고

 

- (void)viewDidUnload

- (void)dealloc에서는 자원해제를 합니다.

 

 

 

먼저 loadView는 UIViewController view의 getter가 호출되었을때  view가 nil인 경우 호출이 됩니다.
처음에 UIViewController가 init되면 view는 아직 로드되지 않은 상태에서 view가 불립니다.
 
이때 loadView가 호출되는 것이지요. loadView의 기본구현은 nibFile이 있을 경우 nibFile을 로드하고 없으면 UIView 를 하나 만들어서 view에 할당합니다. 그리고 viewDidLoad가 호출이 됩니다.
 
 
Interface Builder를 통해 View를 그리는 경우는 주로 loadView를 오버라이드 하기 보다는 viewDidLoad를 구현하도록 도큐먼트에 명시되어 있습니다. 즉 추가적인 View 로드, 초기화 등이 필요하다면 이 viewDidLoad에다가 씁니다. 
 
만약 nib파일을 만들지 않고 코드상에서 view를 그린다면 loadView의 기본구현은 오버헤드가 되므로 loadView를 오버라이드 해서 [super loadView]는 호출하지 않도록 합니다.(하게 되면 쓸대없이 nibFile을 확인하고 빈 UIView가 생성됩니다.)
 
 
대부분의 경우 loadView viewDidLoad순서로 불리고 view가 로드되며 view가 dismiss되면서 UIViewController의 dealloc이 호출되면서 끝납니다.
 
 
viewDidUnload는 아예 불리지도 않는 경우가 대부분이지요.    과연 viewDidUnload는 언제 호출되는가?
viewDidUnload는 viewcontroller가 ui stack에 푸시되어 있는 경우 불려질 수 있습니다.
navigation controller stack에 푸시되거나 presentmodalviewcontroller등으로 view가  다른 view에 의해 가려진 경우 memory warning이 발생하면 가려진 view의 viewcontroller의 viewDidUnload가 호출이 됩니다.
 
NavigationController의 RootViewController가 A이고  A의 view에 어떤 버튼을 누르면 B가 뜬다고 합시다.
그러면 A는 B뒤로 숨게됩니다.  이때 memory warning이 뜨면 메모리 확보를 위해 A의 view는 nil로 세팅되고
a.view = nil이 불리면서 viewDidUnload가 호출됩니다. 
 
그리고 B에서 back을 눌러 다시 A로 돌아가면 view가 다시 호출되어 loadView viewDidLoad순으로 호출된 다음 A의 view가 나타나게 됩니다.
 
 
자 그럼 
 
Interface Builder를 쓰지 않고 구현하는 경우를 생각해 봅시다.
 
@interface TestViewController : UIViewController {
UIButton *button;
}
@end
 
@implementation TestViewController
중략...
 
- (void)buttonClicked:(id)sender {
   NSLog(@"aaaa");
}
 
- (void)loadView {
  _view = [[UIView alloc] init];
  button = [[UIButton alloc] init];
  [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]
  [_view addSubView:button];
}
 
- (void)viewDidUnload {
  [button release], button = nil;
}
 
- (void)dealloc {
  [button release];
  [super dealloc];
}
 
@end
 
요런 모양세가 됩니다.
 
만약 굳이 button의 레퍼런스가 필요없다면
 
 
@interface TestViewController : UIViewController {
  // UIButton *button;
}
@end
 
@implementation TestViewController
중략...
 
- (void)buttonClicked:(id)sender {
   NSLog(@"aaaa");
}
 
- (void)loadView {
  _view = [[UIView alloc] init];
 // button = [[UIButton alloc] init];
  UIButton *button = [[UIButton alloc] init];
  [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]
  [_view addSubView:button];
  [button release];
}
 
- (void)viewDidUnload {
  //[button release], button = nil;
}
 
- (void)dealloc {
  //[button release];
  [super dealloc];
}
 
@end
 
이런 모양이 되겠지요.
 
여기서 viewDidUnload에 button = nil;이 들어간 이유는 viewDidUnload가 불린 뒤에 dealloc가 바로 불릴 수 도 있기 때문이죠. (실제로 이런 경우는 잘 없습니다만;;)
 
 
만약 Interface Builder로 만든 경우라면 어떨까요?
일단 아래에서 outlet도 연결되고 action도 nib에서 다 연결되었다는 가정하에..
 
@interface TestViewController : UIViewController {
  UIButton *button;
}
@property (nonatomic, retain) IBOutlet UIButton *button;
- (IBAction)buttonClicked:(id)sender;
@end
 
@implementation TestViewController
@synthesize button;
- (IBAction)buttonClicked:(id)sender {
}
- (void)viewDidLoad {
}
- (void)viewDidUnload {
  self.button = nil;   // 이것은 [button release], button = nil;과 같겠지요...
}
- (void)dealloc {
  [button release];
  [super dealloc];
}
 
@end
 
interface builder에서 outlet을 연결해주면 로드될때 해당 outlet에 레퍼런스를 할당해 줍니다. 즉 button에 연결이 됩니다.
그런데 view가 언로드 될때는 자동으로 해제되지 않습니다. 따라서 꼭 viewDidUnload에 self.button = nil;과 같이 써주어야 합니다.   그러나 꼭 해주지 않아도 별 문제는 없긴 합니다.  viewDidUnload가 불리고 view만 날라가고 숨겨져 있는 상태에서 button이 해제되지 않은 상태로 남겠지만. 다시 view가 로드될때 nibfile이 로드되면서 self.button 에 값이 할당되므로 기존 button은 역시 release가 되긴 하거든요. 또는 dealloc이 바로 불린다면 [button release];가 불리므로 메모리 해제도 되지요.    하지만 깔끔하지 않을뿐…
 
 
다시한번 말씀드리면 viewDidUnload는 잘 불리지 않는 것처럼 보이지만 view가 다른 view에 가려져 있는 경우 memory warning으로 호출되며,  특히 imagepickerController를 사용할때는 빈도가 아주 높습니다. 따라서 제대로 구현을 안해주면 view가 날라가는 경험을 하게 되기도 하지요…
 

 

 

 

그림으로 설명을 하면 좋을텐데   글로만 줄줄 썼네요 혹시 이해가 안되는 게 있으면... 댓글로 질문을 써주세요

 

 

ebizboy 님의 게시글 댓글
  • 주소복사
  • Facebook
  • X(Twitter)
댓글 • [3]
정민군
IP 58.♡.40.146
11-22 2010-11-22 23:31:16 / 수정일: 2017-04-30 01:45:25
·
강좌 감사합니다~~ 찬찬히 읽어봐야겠네요 ^^
지푸라기
IP 119.♡.220.15
11-23 2010-11-23 01:48:30 / 수정일: 2017-04-30 01:45:25
·
loadView와 viewDidUnLoad가 이런 쓰임새가 있었군요.
이녀석들 잘 안써서 언제 쓰나...싶었는데...^^
한가지 질문이 있는데요..

IB를 사용하지 않고 뷰를 그릴때 loadView에 쓰는게 더 좋은건가요?
지금까진 viewDidLoad에 적어줬거든요.....
좋은 강좌 감사합니다!!!
ebizboy
IP 175.♡.81.63
12-15 2010-12-15 11:36:04 / 수정일: 2017-04-30 01:45:25
·
loadView를 쓰던 viewDidLoad를 쓰던 별 상관 없습니다.
새로운 댓글이 없습니다.
이미지 최대 업로드 용량 15 MB / 업로드 가능 확장자 jpg,gif,png,jpeg,webp
지나치게 큰 이미지의 크기는 조정될 수 있습니다.
목록으로
글쓰기
글쓰기
목록으로 댓글보기 이전글 다음글
아이디  ·  비밀번호 찾기 회원가입
이용규칙 운영알림판 운영소통 재검토요청 도움말 버그신고
개인정보처리방침 이용약관 책임의 한계와 법적고지 청소년 보호정책
©   •  CLIEN.NET
보안 강화를 위한 이메일 인증
안전한 서비스 이용을 위해 이메일 인증을 완료해 주세요. 현재 회원님은 이메일 인증이 완료되지 않은 상태입니다.
최근 급증하는 해킹 및 도용 시도로부터 계정을 보호하기 위해 인증 절차가 강화되었습니다.

  • 이메일 미인증 시 글쓰기, 댓글 작성 등 게시판 활동이 제한됩니다.
  • 이후 새로운 기기에서 로그인할 때마다 반드시 이메일 인증을 거쳐야 합니다.
  • 2단계 인증 사용 회원도 최초 1회는 반드시 인증하여야 합니다.
  • 개인정보에서도 이메일 인증을 할 수 있습니다.
지금 이메일 인증하기
등록된 이메일 주소를 확인하고 인증번호를 입력하여
인증을 완료해 주세요.