window.onload

사용법 : window.onload = function(){ 시작시 실행될 내용 }

window.onload = function ()
{
실행함수();
}

참고로 window.onload와 는 동시에 사용을 할 수 없습니다.
가 실행이 되면 window.onload는 실행이 되지 않는 문제가 있습니다.

동시에 사용하려면 window::onload() 이렇게 하면 됩니다.
사용법 : function window::onload(){ 시작시 실행될 내용 }

실행 순서는 가 먼저 실행되고, 이어서 window::onload()가 실행됩니다.

meta 태그

meta

HTML 문서가 어떤 내용을 담고 있고, 문서의 키워드는 무엇이며, 누가 만들었는지 등의 문서 자체의 특성을 담고 있다.
브라우저나 검색 로봇에게 해당 페이지의 정보를 알려주는 기능.

이 표기방법 중 페이스북의 오픈그래프(open graph) 프로토콜을 사용하는 것이 og 태그이다.

속성
– name : 문서의 메타데이터를 설정합니다.
– http-equiv : 전처리 구문 지시자입니다.
– content : name속성이나 http-equiv속성을 사용했을 때 함께 명시합니다.
– charset : 문자 인코딩 방식을 명시합니다.

설명
– name, http-equiv, charset 속성중 하나만 사용할 수 있습니다.
– 만약 name이나 http-equiv중 하나를 사용했다면 반드시 content속성을 사용해야 합니다. 그렇지 않으면 그것들은 생략되어야 합니다.
– 한 문서에서 charset속성을 가진 하나의 meta속성만 사용할 수 있습니다.

 

터치기기를 위한 디자인

  1. 가장 중요한 터치 영역을 확인하라

    • 손으로 잡는 모양에 따라 다른 부분이 중요
    • 한 손 사용(49%) : 한 손 엄지가 닿는 부분 중요
    • 양손 사용: 한 손 엄지/한 손 검지(36%), 양손 엄지(15%)
  2. 콘텐츠를 컨트롤 위에 배치하라

    • iOS – 화면 아래에 컨트롤 배치
    • 안드로이드 – 화면 위에 컨트롤 배치(시스템 메뉴 위에 다시 앱 메뉴가 배치되면 곤란)
    • 모바일 웹 – 페이지 아래에 컨트롤 배치(필요하면 점프해서 가도록 구성)
  3. 선례에 따르는 것이 좋다

    • 태블릿은 아래에 메뉴를 배치 하는 것이 좋지 않음

    • 태블릿은 위나 잡았을 때 엄지가 닿는 좌우 측면이 유용

    • 터치 랩탑의 경우는 다름

      • 좌우 영역이 유용한 점은 비슷함
      • 위 영역보다 아래가 나음. 세워진 화면에서 위까지 손 들기 귀찮아 함
  4. 화면 크기만 보고 터치 특성이 같다고 생각하면 안 된다

    • 포인팅 장치의 정확도는 기기마다 다르다

    • 정확도에 따라 컨트롤 크기를 다르게 설정할 필요 있음

    • CSS4 – pointer media query 참고

      • coarse: 스마트폰, 터치스크린 / 위 리모콘, 키넥트
      • fine: 스타일러스 화면 / 마우스, 터치패드
  5. 모든 데스크탑 디자인도 터치를 고려해서 만들어야 한다.

    • 마우스 오버는 터치할 때 무용지물임
    • 사람들이 터치로 사용하는 제품에는 마우스 오버 효과를 쓰면 안됨
  6. 터치 영역은 최소 44*29 픽셀 이상으로 하라

    • 최소 7mm 는 확보해야 엄지로 터치가 가능하다
    • 7mm = 44 pixel = 2.75em (44*29 픽셀이 진짜 최소 크기)
    • 웹은 44px , iOS 앱은 44pts, 안드로이드 앱은 44dp 로 맞추면 무난하다 (일반적으로 가장 널리 사용되는 160dpi 디스플레이에 맞춘 크기임)
  7. 수직으로 44 픽셀 vertical rhythm을 만들어라 (44픽셀 줄 간격에 맞춰 디자인 한 것처럼 만들라는 뜻)

  8. 아이콘이 클 수록, 가까이 있을수록 터치가 쉽다 (Fitts의 법칙)

    • (스마트와치를 멀리서 바라보고 쓰려면 버튼이 커야 한다)
  9. 스크린만 생각하고 디자인하지 말고, 센서를 생각하고 디자인하라

    • (최근 모바일을 먼저 설계하고 다른 것을 나중에 하라는 원칙이 유명한데, 이제 센서를 먼저 고민하고 화면을 나중에 생각하는 시대가 오고 있다. 그러니 화면을 고민하기 전에 센서를 먼저 생각하라는 뜻)

http://cfile4.uf.tistory.com/image/2516BE37536B331439FFAD

http://cfile25.uf.tistory.com/image/273DFA3A536B33141809A3

Precompiled Header

Search Bar

<UISearchResultsUpdating>

UISearchBar

UISearchController 

- (instancetype)initWithSearchResultsController:(nullable UIViewController *)searchResultsController;

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController;

Precompiled Header

  • 컴파일전에 자주 사용하는 헤더파일을 미리 컴파일하여 캐쉬에 저장
  • 해더파일 컴피알 시간을 다눅시기키 위해 사용
  • 전역적으로 사용하고 싶은 데이터를 헤더 파일 선언하고 Prefix.pch

ViewController.h 에 있는 #import 를
PrefixHeader.pch 파일에 옮겨준다.
그안에 새로만든 헤더파일 #import "BaseBox.h"을 넣어주면 전역적으로 사용 가능하다.

Prefix.pch 설치

* 경로는 해당 프로젝트아래의 폴더명부터 넣으면 된다.

[[UIDevice currentDevice] systemVersion]

Preprocessor Macros – Debug

debug mode

  • 내 test code가 배포(release)될때 실수로 실행되지 않게 할 때 유용하다
  • setting

# ifdef DEBUG 

    // debug only code 
    // DEBUG=1
    
    NSLog(@"debug mode");
#endif  

혹은 release 될 때만 실행

# ifdef RELEASE

    // debug only code 
    // RELEASE=1
    
    NSLog(@"debug mode");
#endif  

#ifdef TARGETOSSIMULATOR

segue

Segue

segue는 object

show detail 은 뷰 스위치
modally 밑에서 위로
popover 위에서 아래로 pop

shouldPerformSegueWithIdentifier:sender:

override해서 identifier 가져와서, 로그인할거냐 말거냐, 세그위에를 진행할거냐 말거냐를 정한다.

prepareForSegue:sender:

awakeFromNib:

커스텀뷰를 만드는데 스토리보드가 사용될때 여기서 한다.

Unwind Segue

여기서 맞춰야할건 액션과 세그웨이
Exit 된다음에 돌아올 때 아래 메서드가 불림

- (IBAction)myUnwindAction:(UIStoryboardSegue * )unwindSegue
(unwindSegue 목적지)

Manual Segue (수동 세그웨이)

“Segue를 코드로 짜겠다”

[self performSegueWithIdentifier:@"segueName" sender:self];

App 생명주기

Event에 대한 처리

  • touch
  • remote control
  • lacation : CoreLocation 객체
  • redraw : 다시 그림.

Excution State

iOS App 은 항상 아래의 5가지 중 하나의 상태를 가진다.

  • Not Running : 앱이 실행되지 않은 상태, 또는 실행이 되었지만 시스템에 의해 종료된 상태

  • Inactive : 실행중이지만 이벤트를 받고있지 않은 상태. Foreground 로 진입은 했으나 이벤트는 아직 받지 못한 상태. iOS 앱은 다른 두 상태 사이에서 상태변환을 할 때 중간 단계로 짧은 시간동안 InActive 에 머물게 된다. 예를 들어 앱 실행중 알림 등이 화면을 덮어 앱이 실질적으로 이벤트를 받지 못하는 상태.

  • Active : 앱이 화면에 보이고 이벤트도 받으며 실행되는 정상 상태. 일반적인 앱의 실행상태이다.

  • Background : 대부분의 앱은 홈버튼을 눌렀을 때 Suspended 상태가 되기 전 잠시 Background 상태에 머문다. 이 상태에서 앱은 일정 시간 일부 코드를 수행할 수 있지만 사용자의 이벤트를 받을 수는 없다. Background에서 추가적인 코드를 수행할 필요가 있는 경우 Background 상태로 남아 일정 시간동안 코드를 수행할 수 있다. 앱이 실행되자마자 Background 로 진입하는 앱은 Inactive 상태를 거치지 않고 바로 Background 상태로 진입한다. ex) 음악실행, 트래킹…

  • Suspended : 앱 실행이 중단된 상태. Suspended 상태에서는 앱은 메모리에 존재하지만 아무런 코드를 수행하지 않는다. System은 앱을 아무런 통보 없이 Background상태에서 자동으로 Suspended 상태로 바꿀 수 있다. 메모리 부족현상이 발생하면 System은 별다른 통보 없이 Suspended 상태의 앱을 종료할 수 있다.

background에 있는데 메모리를 많이 잡아먹거나, 오래 사용안하면 suspened(종료)로 가는 경우도 있다. ex) 포켓몬고 하다가 전화왔을때 통화후 돌아가면 종료되어있다. 메모리 많이 먹어서

UIApplication Delegate 는 이러한 상태 전이에 반응할 수 있도록 메소드를 정의해 놓고 있다.

  • application:didFinishLaunchingWithOptions : 앱 런칭 시점에서 Application 단의 초기화 작업등을 수행할 수 있다.
  • applicationDidBecomeActive : Active 상태로 전이 될 때 호출된다. Background 앱이 다시 호출되어 Active 상태가 되도 호출된다.
  • applicationWillResignActive : 앱이 Active 상태를 벗어날 것을 알려준다.(ex. 홈 버튼을 누르면 호출됨) 단, 앱이 Background 상태로 전이된다는 보장은 없다. 이 상황에 잠깐 머물다가 다시 바로 Active 상태로 바뀔 수도 있다.
  • applicationDidEnterBackground : Background로 진입. 언제든 System에 의해 Suspended 상태로 전이될 수 있다. 나중에 재생성할 수 있는 모든 리소스들을 제거하고 사용자 데이터를 저장한는 등의 작업을 수행하는 용도로 사용될 수 있다. 이 메소드 호출 이전에 applicationWillResignActive가 호출된다.
  • applicationWillEnterForeground : Background를 벗어나 Foreground로 진입될 것을 알려준다.(아직 Active 상태는 아님) applicationDidEnterBackground 에서 해제한 리소드들을 재생성하는 용도로 사용할 수 있다.이 메소드 호출 뒤에 applicationDidBecomeActive 가 호출된다.
  • applicationWillTerminate : 앱이 종료될 것임을 알려준다. 앱이 Suspended 상태에서 종료되는 것이라면 호출되지 않는다.

http://developer.apple.com

Network

Network

연결을 통해 컴퓨터의 자원을 공유하는 것

클라이언트 서버 모델 (client-server model)

  • network architecture 중 하나
    • 또다른 network 종류로는 p2p가 있다. (peer-to-peer network)
    • 중앙서버 없이 컴퓨터와 컴퓨터간을 연결. 개인이 공급자이자 소비자가 됨.
  • setver : client 의 요청에 따라서 데이터를 제공해 주는 컴퓨터
  • client : 서버로 부터 요청한 데이터를 받는 컴퓨터
  • 각각의 컴퓨터가 client, server의 역할에 맞게 구성되어 network 통신이 이뤄진다면 우린 이걸 클라이언트 서버 모델이라고 부를 수 있다.

Protocol

  • http
  • https
  • ftp
  • smtp
  • SSH 맥에서 다른 컴에 연결할 때

URL

Uniform Resource Locator, 문화어: 파일식별자
– 네트워크상에서 자원이 어디있는지를 알려주기 위한 규약

URI

Uniform Resource Identifier

  • url : 특정자원의 위치값 (실제파일 있음)

http://naver.com/index.html

  • uri : Restful 구조. 특정자원의 함수 (실제 파일 없음. 이름표)

http://naver.com/basefile

![](https://4.bp.blogspot.com/-AG9PUSpz2Ss/UV1o7jnPRlI/AAAAAAAAA90/1qI9M2lZqnE/s1600/RestfuArchitecture.jpg

http request

uri 를 이용해서 server에 데이터를 요청한다.
크게 header와 body로 구조를 나눌 수 있다.
http method를 사용해서 요청메시지를 보낸다. (권장)

참고 http://goo.gl/xjH2ke

http request 구조

Request-Line
Header

[Message-body]

Request Header

header는 정보

response 헤더 도 있다.

  • Host

  • Accept : 항목. 항목보고 판단. 틀리면 reject

  • User-agent

Contents Type

  • 서버, 클라이언트 간에 어떠한 데이터를 주고 받을 수 있는지 명시하는 Type

대표 Type 종류

Multipart 복잡한거 주고받을 때. 예를 들어 이미지랄지 파일 업로드 할때 쓴다.

Message Body

GET GTTP Method의 파라미터는 URL에 포함시켜서 정보를 보낸다.

ex) http://siteURI/age?firstName=joo&lastName=ym

GET 을 제외한 나머지 Method의 파라미터는 content-type에 맞는 형식으로 body message에 포함시켜서 요청을 보낸다.
(확인하는 정도의 수준으로 보냄)

형식 : 물음표 키=밸류&키=밸류

보안에 취약

ATS

ATS (app transport security)

  • iOS9 이상의 버전에는 ATS 기술이 기본적으로 적용된다. ATS는 앱과 웹서비스 간 연결보안을 강화하는 기술로 이 기술이 적용되면 기본 iOS 앱에서 암호화도지 않은 HTTP 통신은 OS 내부에서 강제적으로 차단된다.

  • 보안이 안돼있는 요청을 iOS에서 거부

using http request

request 객체 만들때 필요한 4가지

  • url 통해서 객체 만들고 NSURL
  • 메소드 종류, 컨텐츠 타입
  • 바디 (데이터값 바디에 넣으면 된다. 헤더에 뭔가 필요하다면 헤더 추가)
  • 필요하다면 컨텐츠타입

폼데이터 키,값,&,키,값,& username=%@&device=%@

task 종류 3가지 – 업로드, 다운로드, 데이터테스크

포스트는 업로드 방식

리퀘스트를 보낼때 정보가 헤더에 있다. 아이폰에서 보냈는지 맥에서 보냈는지 등등
서버는 헤더를 보고 바디를 참고

컨텐츠 타입

대표 type 종류

Thread

Thread

process 내에서 실행되는 흐름의 단위.

멀티thread – 여러개의 thread를 동시에 진행이 되는 것처럼 보이게끔

process – 프로그램이 메모리에 올라가 실행이 되는 것

iOS Thread

  • 모든 앱은 기본적으로 main thread를 가지고 있다.
  • 필요하면 따로 추가적인 thread를 만든다.
  • use UIKit classes only from your app’s main thread.
    (UI 는 무조건 main thread에서 돌려라)

    • 이런 이유때문에 추가적인 thread가 안돌아가는 경우가 있다

만약 작업시간이 오래걸리는 작업을 main thread에서 실행된다면 어떻게 될까?
ㄴ 끝날때까지 멈춰있다

When is use

  • 동시에 작업이 필요한 경우
  • 멀티코어 process를 사용하기 위해
  • 중요한 작업에 방해받지 않기 위해
  • 상태를 계속 감시해야 할 경우가 필요할 때

동기 / 비동기

  • 비동기 – 동시에 일어나지 않는, 같은 시기가 아닌
  • 동기 – 동시에 일어나는, 같은 시기

nonatomic, atomic의 문제

  • 디자인패턴에 의한 비동기처리
    • 델리게이트, 셀렉터, 블록, 노티피케이션
  • 큐를 이용한 비동기처리 방법은 GCD로 가능
    • dispatchsyc, dispatchasync

교착상태 (deadlock)

두 개 이상의 작업이 서로 끝나기만 기다리다 아무것도 완료하지 못하는 상태

Multi thread

iOS에서 Multi thread 방법

  • NSThread : 직접 thread를 만들어서 제어하는 방식

  • GCD : Block기반의 기법으로 코드 가독성이 좋고 간편하다.
    (블럭의 가장 큰 장점은 멀티코어)

  • NSOperation : GCD기반의 rapper Class. 간단하게 사용가능하고 고수준의 API를 제공한다. 성능이 느린편.

  • performSelector : Selector를 이용한 방식, ARC이전에 주로 사용한 방식이었으나 GCD이후엔 많이 사용되지 않는다.

  • NSTimer : 간단한 interval Notification 를 제공해 주는 Class. 특이하게도 NSTimer는 mainLoop에서 실행된다.

NSThread

  • main thread 외 다른 thread를 만드는 클래스
  • UI는 절대 추가Thread에서 실행시키면 안된다.
  • cancel 명령은 강제 종료가 되지 않는다 (그저 BOOL 값)
  • Selector로 실행된 Method가 종료후 자연스럽게 Thread도 종료

NSThread 요소

  • Initializing
  • Starting a Thread
  • Stopping a Thread
  • Execution State

GCD

  • 비동기로 작업을 수행시키는 강력하고 쉬운 방법
  • 멀티코어 프로세서에서 최적화되어 작동한다
  • dispatch queue를 이용해서 작업들을 컨트롤한다.
  • Block으로 구현된다.

dispatch queue

dispatch queue는
queue에 쌓여있는 일들을 cpu 에 분배한다.

serial queue / concurrent queue

구조적 분류

  • main dispatch queue (main thread)
  • Global queue (4개를 가지고 있다)

Main dispatch queue

  • main thread 를 가르키며 기본 UI를 제어하는 queue
  • Serial 방식으로 들어온 순서대로 진행되며 앞에 작업이 종료될 때까지 뒤의 작업들은 대기한다.

dispachqueuet global_queue =
//type name

dispatchgetmain_queue();

(C의 문법. swift에서는 다르다.)

Private dipatch queue

  • 사용자정의 queue
  • 사용자가 만든 queue는 serial

dispatch_after

얼마간의 시간이 지난 후에 queue에 집어 넣어라
// 다음 queue들이 차례로 들어가다가 일정한 시간 후 dispatch_after가 끼어듬. 그리고 다시 async 진행

dispatchqueuet queue = dispatchqueuecreate(“com.wing.test”, DISPATCHQUEUEU
dispatchafter
dispatch
async
dispatchasync
dispatch
async
dispatchasync
dispatch
async
dispatchasync
dispatch
async
dispatch_async

dispatchbarrierasync 예제
async 지만 칸막이. (이마트 계산대 컨베이어 위에 칸막이 막대. 앞에꺼 처리 다할때까지)
dispatchasync
dispatch
async
dispatchasync
dispatch
barrierasync
dispatch
async
dispatchasync
dispatch
async

GCD 함수 – 추가

//큐에서 작업을 실행하지 못하도록 정지시킨다.
void dispatchsuspend(dispatchobject-t object);
(맨끝 object는 큐)

//정지도니 큐를 재개
void dispatch_resume(

스탑워치 GCD로 만들기

  • dispatch_source 사용하기

//dispatchsource 생성
self.timer = dispatch
sourcecreate(DISPATCHSOURCETYPETIMER, 0, 0, dispatchgetmain_queue());

//시간 설정
//dispatchsourcet source, dispatchtimet start, uint64t interval, uint64t leeway)

//이벤트 정하기
dispatchsourceseteventhandler(self.timer, ^{
[self changeText:[NSNumber numberWithInteger:self.gcdSecond]];
self.gcdSecond++;
});

//시작
dispatch_resume(self.timer);

//멈춤
dispatch_suspend(self.timer);

Singleton, NSUserDefault, Notification

Singleton

전역객체

singleton pattern

  1. 싱글톤이란? 어플리케이션 전 영역에 걸쳐 하나의 클래스에 단 하나의 인스턴스(객체) 만을 생성 하는 것을 싱글톤 패턴이라 한다.
  2. 이걸 쓰는 이유는 어플리케이션 내부에서 유일하게 하나만 필요한 객체에 사용한다. (세팅, 데이터 등) (원래 객체의 생성은 재사용을 염두에 두지만)
  3. 클래스 메서드로 객체를 만들며 static 을 이용해서 단 1개의 인스턴스를 만든다.
  4. 앱 내에서 공유하는 객체를 만들 수 있다.
data 전역변수, 정적변수
stack 지역변수 (만들었다 사라질 놈들)
heap 객체
code
//singleton.h

@interface DataCenter : NSObject

+ (instancetype)sharedInstance ;
@end
//singleton.m

@implementation DataCenter

+ (instancetype)sharedInstance {

static DataCenter * dataCenter = nil;

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    dataCenter = [[seslf alloc] init];
    });
    return dataCenter;
}
@end

singleton pattern 예제

// 스크린 정보를 가지고 있는 객체
UIScreen *screen = [UIScreen mainScreen];

// 사용자 정보를 저장하는 객체
NSUserDefaults *data = [NSUsesrDefault standardUserDefaults];

// 어플리케이션 객체
UIApplication *app = [UIApplication SharedApplication];

//파일 시스템 정보를 가지고 있는 객체
NSFileManager *fileManager = [NSFileManager defaultManager];

NSUserDefault

저장방법 – 서버 – Core data – plist (property list)

사용자의 정보를 저장하는 싱글톤 객체 – 간단한 사용자 정보를 저장/ 불러오기가 가능하게 만든 객체 – 내부적으로 plist 데이터에 저장되어 보안이 강하지 않다. (plist – 파일형태:뚫을 수 있다 / core data – 열기 힘들다)

주요항목

+ (NSUserDefaults * )standardUserDefaults;
// data - Dictionary 형태 (jSON)

// 데이터 불러오기
- (nullable id)objectForKey:(NSString * )defaultName;

// 데이터 저장하기
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;

// 데이터 지우기
- (void)removeObjectForKey:(NSString * )defaultName;

// 예제
// *key값은 통일시켜야 한다.

// 데이터 저장
[[NSUserDefaults standardUserDefaults] setObject:@"sean" forKey:@"name"];

// 데이터 불러오기
NSString * nameData = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"];
NSLog(@"저장된 이름은 %@입니다", nameData);

Notification

  • Push Notification
  • Local Notification

Protocol

복수의 컴퓨터 사이나 중앙 컴퓨터와 단말기 사이에서 데이터 통신을 원활하게 하기 위해 필요한 통신규약. 신호 송신의 순서, 데이터의 표현법, 오류검출법 등을 정함.

객체지향에서는 두 클래스 간의 약속 이런 이름의 함수를 만들어라

  • Objective-C 에서는 Delegate 라는 이름으로 사용한다.

객체 간 통신

  • Delegate 방식은 1:1 통신방식
    • 한번에 여러 객체와 통신하는 방법은 없을까?

NSNotificationCenter

  • 특정 이벤트가 발생하였음을 알리기 위해 불특정 다수의 객체에게 알리기 위해 사용하는 클래스
  • 어떤 객체라도 특정 이벤트가 발생했다는 알림을 받을 것이라고 Observer로 등록을 해두면 NSNotificationCenter 가 모든 Observer 객체에게 Notification 을 보내준다.
  • 페이스북에서 친구를 등록해주면 친구의 이벤트가 내 뉴스피드나 알림으로 오는 것과 같은 이치

Notification 구조

  1. 객체A (observer)가 NotificationCenter 에 자신이 Notification을 받을 거라고 등록 (addObserver)
  2. 객체B 가 필요한 시점에 Notifacation 송출 (postNotifacation)
  3. NotifacationCenter 에서 적절한 객체와 메서드를 찾아서 호출

Notifacation 주요 Method


// Initializing

+ (NSNotificationCenter *)defaultCenter;

// Add Observer
- (void)addObserver:(id)Observer // self
           selector:(SEL)aSeletor  // @selector(noti:)
               name:(NSStirng *)aName // name:키값
             object:(id)anObject;  //object 필터역할 주로 nil


// Post Notification
- (void)postNotifacation:(NSNotification *)Notification;
- (void)postNotifacationName:(NSStirng *)aName
                      object:(id)anObject;
- (void)postNotifacationName:(NSStirng *)aName
                      object:(id)anObject
                    userInfo:(NSDictionary *)aUserInfo;
// Remove Observer
- (void)removeObserver:(id)Observer;

- (void)noti:(NSNotification *)notiSender {

}            


// 예제
// ========== Observer
- (void)addObserverMethod(
  [[NSNotificationCenter defaultCenter] addObserver:self      
                                           selector:@selector(trakingPost:)
                                               name:@"NotificationKey"
                                             object:nil];
}

- (void)trakingPost:(NSNotification *)noti{
  NSStirng * notiText = noti.object;
  // notiText == @"wing"

}

//=========== Poster
- (void)postMethod {
  [[NSNotificationCenter defaultCenter] postNotifacationName:@"NotificationKey"
                object:@"wing"];

}        

System Notification Key

NSStirng * const UIApplicationDidEnterBackgroundNotification;
NSStirng * const UIApplicationWillEnterForegroundNotification;

NSStirng * const UIKeyboardWillShowNotification;
NSStirng * const UIKeyboardDidShowNotification;
NSStirng * const UUIKeyboardWillHideNotification;
NSStirng * const UIKeyboardDidHideNotification;

NSStirng * const UITextFieldTextDid;
NSStirng * const UITextFieldTextDid;
NSStirng * const UITextFieldTextDid;


//예제
//============ Observer
- (void)addObserverMethod {
  [[NSNotificationCenter defaultCenter] addObserver:self      
                                           selector:@selector(trakingPost:)
                                           name:UIKeyboardDidShowNotification
                                           object:nil];
}

- (void)didShowkeyboardNoti:(NSNotification *)noti{
  // 키보드가 올라온 후 불리는 Method
}

//============ Poster

키보드가 올라올때 시스템에서 자동으로 Noti를 Post해준다.

chief choi 예제

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell-v"];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell-v"];
    }

    switch (indexPath.section) {
        case 0:{
            UISwitch *switchInCell = [[UISwitch alloc] initWithFrame:CGRectZero];
            cell.accessoryView = switchInCell;
        }
            break;
        case 1:{

            UISwitch *s1 = [[UISwitch alloc] init];
            [s1 addTarget:self action:@selector(changedSwitchValue:) forControlEvents:UIControlEventValueChanged];
            cell.accessoryView = s1;


//            NSUserDefaults *user = [NSUserDefaults standardUserDefaults];

//            NSLog(@"%ld %d", indexPath.row, ![user integerForKey:@"switch"]);
//            if ([[user objectForKey:@"switch"] integerValue]) {
//                [user setObject:@"1" forKey:@"switch"];
//            } else {
//                NSInteger cnt = [[user objectForKey:@"switch"] integerValue] + 1;
//                [user setObject:[NSString stringWithFormat:@"%ld", cnt] forKey:@"switch"];
//            }
//            
////            if (![user integerForKey:@"switch"]) {
////                [user setInteger:1 forKey:@"switch"];
////                NSLog(@"%ld", [user integerForKey: @"switch"]);
////            } else {
////                NSInteger temp = [user integerForKey:@"switch"] + 1;
////                NSLog(@"temp = %ld",temp);
////                [user setInteger:temp forKey:@"switch"];
////            }
//
//            NSString *str = [NSString stringWithFormat:@"switch%ld", [[user objectForKey:@"switch"] integerValue]];
//            s1.on = [NSNumber numberWithBool:[[NSUserDefaults standardUserDefaults] objectForKey:str]];
//            s1.tag = [[user objectForKey:@"switch"] integerValue];


//            [NSUserDefaults standardUserDefaults] setObject:<#(nullable id)#> forKey:<#(nonnull NSString *)#>


            break;
        }
        case 2:{

            UISwitch *switchInCell = [[UISwitch alloc] initWithFrame:CGRectZero];
            cell.accessoryView = switchInCell;

            break;
        }

    }
    //        switch (indexPath.section) {
    //            case 0:
    //                cell.textLabel.text = [self.array1 objectAtIndex:indexPath.row];
    //                break;
    //            case 1:
    //                cell.textLabel.text = [self.array2 objectAtIndex:indexPath.row];
    //                break;
    //            case 2:
    //                cell.textLabel.text = [self.array3 objectAtIndex:indexPath.row];
    //                break;
    //            default:
    //                cell.textLabel.text = [self.array4 objectAtIndex:indexPath.row];
    //                break;
    //        }]]
    cell.textLabel.text = self.array[indexPath.section][indexPath.row];

    if (indexPath.section == 3) {
        [cell.textLabel setTextColor:[UIColor redColor]];

    }


    //        if (cell == 0) {
    //            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell-v"];
    //
    //
    //        }






    return cell;
}