용어 정리

Stateless 서버

  • Stateful 서버
    Client의 상태를 유지하여 이 정보를 서비스 제공에 이용
    Stateful 서버의 예: 세션을 유지하는 웹서버 ex) 유저가 로그인 시, 세션에 로그인이 되었다는 정보 저장
    메모리 또는 데이터베이스 시스템에 담을 수도 있음.
  • Stateless 서버
    Client 상태를 유지하지 않는 것.
    상태 정보를 저장하지 않으면, 서버는 클라이언트측에서 들어오는 요청만으로 작업 처리
    확장성(Scalability)이 높아짐

모바일 어플리케이션에 적합

안전한 API를 만들기 위해 쿠키와 같은 인증 시스템은 이상적이지 않음.

 

인증정보를 다른 어플리케이션으로 전달

ex) OAuth token: 소셜 계정들을 이용하여 다른 웹서비스에서도 로그인 가능

 

보안

토큰 기반 인증 시스템은 어플리케이션의 보안을 높힐 수 있음.

 

왜 사용할까? - 서버 기반 인증의 문제점

  • 세션: 유저가 인증을 할 때, 서버는 이 기록을 서버에 저장
    로그인 중인 유저의 수가 늘어난다 => 서버의 램 과부화
  • 확장성
    (확장? 단순히 서버의 사양을 업그레이드 하는것이 아니라, 더 많은 트래픽을 감당하기 위하여 여러개의 프로세스를 돌리거나, 여러대의 서버 컴퓨터를 추가 하는것)
    세션을 사용하면서 분산된 시스템을 설계하는건 불가능한것은 아니지만 과정이 매우 복잡해집
  • CORS(Cross-Origin Resource Sharing)
    세션을 사용하면서 분산된 시스템을 설계하는건 불가능한것은 아니지만 과정이 매우 복잡해짐

토큰 기반 시스템의 작동 원리

  1. 유저가 아이디와 비밀번호로 로그인을 합니다
  2. 서버측에서 해당 계정정보를 검증합니다.
  3. 계정정보가 정확하다면, 서버측에서 유저에게 signed 토큰을 발급해줍니다.
    여기서 signed 의 의미는 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature 를 지니고 있다는 것입니다
  4. 클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청을 할 때 마다, 해당 토큰을 함께 서버에 전달합니다.
  5. 서버는 토큰을 검증하고, 요청에 응답합니다.

웹서버에서 토큰을 서버에 전달 할 때에는, HTTP 요청의 헤더에 토큰값을 포함시켜서 전달합니다.

 

토큰의 장점

무상태, 확장성, 보안성, 여러 플랫폼 및 도메인, 웹 표준 기반

 

 

 

 

Ref.

https://velopert.com/2350

 

 

'iOS > iOS 기본기' 카테고리의 다른 글

Autolayout & Size classes 정의  (0) 2019.12.22
[iOS] Delegate, Notification, KVO 비교 및 장단점 정리  (0) 2019.12.10
[iOS] Layout - Safe Area  (0) 2019.12.09
[iOS] frame vs. bounds  (0) 2019.12.09
[iOS] int vs NSInteger vs NSNumber  (0) 2019.12.05

Higher-Order function (고차 함수)

  • 함수형 언어에서는 함수도 '값(value)'으로 취급
  • 함수를 파라미터로 전달할 수 있고, 반환도 할 수 있음.
  • Swift는 map, flatmap, filter, reduce 함수 제공

 

Map

  • Collection 기준으로 다른 Collection을 만들어 낼 때 사용
  • 파라미터에 Closure를 사용하여 array의 요소들을 변형 시킴.
let numbers = [1, 2, 3, 4, 5]

for number in numbers {
	let formateedNumber = "\(number)$"
    formateedNumbers.apend(formattedNumber)
}

let mappedNumbers = numbers.map { "\($0)$" }

 

FlatMap

  • Array의 차원을 1레벨 flat 해줌.
  • flatten() 메소드와 같은 결과 => flatten() + map = FlatMap
  • 3가지 경우일 때 사용
    1. non-nil인 결과들을 가지는 배열을 리턴
    2. 주어진 Sequence내의 요소들을 하나의 배열로써 리턴
    3. 주어진 Optional이 not-nil인지 판단 후 unwrapping하여 closure 파라미터로 전달
let optionalArray: [Int?] = [1, 2, 3, 4, nil]
// Optinal Array :  [Optional(1), Optional(2), Optional(3), Optional(4), nil]

let flatMappedArray = optionalArray.flatMap { $0 }
// flatMapped Array :  [1, 2, 3, 4]



let nestedArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flatMappedNestedArray = nestedArray.flatMap { $0 }
// flatMapped Nested Array :  [1, 2, 3, 4, 5, 6, 7, 8, 9]



let optional: Int? = 8
let value = optional.flatMap { $0 > 0 ? $0 : -$0 }
// value :  Optional(8)

 

하지만, 첫번째 경우(non-nil인 결과를 가지는 배열 리턴)에서 flatMap을 사용 시 deprecated되었다는 컴파일러의 응답!

=> 이런 경우에는 compactMap을 사용하라고 Swift 4.1부터 변경됨. (남용을 막기위해서 인 듯)

 

 

CompactMap

flatMap을 사용할 시에 단순히 non-nil 결과값들을 얻고 싶으면 compactMap()을 사용!!

 

let optionalArray: [Int?] = [1, 2, 3, 4, nil]
// Optinal Array :  [Optional(1), Optional(2), Optional(3), Optional(4), nil]

/*
 * flatMap() vs compactMap()
 */

let flatMappedArray = optionalArray.flatMap { $0 }
// flatMapped Array :  [1, 2, 3, 4]

let compactMappedArray = optionalArray.compactMap { $0 }
// compactMapped Array :  [1, 2, 3, 4]

 

 

 

Ref.

https://ontheswift.tistory.com/22

세 가지 패턴이 나오게 된 배경

하나의 객체가 다른 객체와 소통은 하지만 묶이기(coupled)는 싫을 때

 

세 패턴 모두 특정 이벤트가 일어나면 원하는 객체에 알려주어 해당되는 처리를 하는 방법을 가지고 있다. 

하지만, 다른 객체와 종속되어 동작하는 것은 '재사용성'과 '독립된 기능 요소' 측면에서 바람직하지 않다.

그러므로, Delegateion, Notification, KVO를 사용한다.

 

Delegate vs. Notification vs. KVO 장단점 비교

  Delegate Notification KVO
장점
  • 매우 엄격한 Syntax로 인해 프로토콜에 필요한 메소드들이 명확하게 명시됨.
  • 컴파일 시 경고나 에러가 떠서 프로토콜의 구현되지 않은 메소드를 알려줌.
  • 로직의 흐름을 따라가기 쉬움.
  • 프로토콜 메소드로 알려주는 것뿐만이 아니라 정보를 받을 수 있음.
  • 커뮤니케이션 과정을 유지하고 모니터링하는 제 3의 객체(ex: NotificationCenter 같은 외부 객체)가 필요없음.
  • 프로토콜이 컨트롤러의 범위 안에서 정의됨.
  • 많은 줄의 코드가 필요없이 쉽게 구현이 가능.
  • 다수의 객체들에게 동시에 이벤트의 발생을 알려줄 수 있음.
  • Notification과 관련된 정보를 Any? 타입의 object, [AnyHashable: Any]? 타입의 userInfo로 전달할 수 있음.
  • 두 객체 사이의 정보를 맞춰주는 것이 쉬움.
  • new/old value를 쉽게 얻을 수 있음.
  • key path로 옵저빙하기 때문에 nested objects도 옵저빙이 가능함.
단점
  • 많은 줄의 코드가 필요.
  • delegate 설정에 nil이 들어가지 않게 주의해야함. 크래시를 일으킬 수 있음.
  • 많은 객체들에게 이벤트를 알려주는 것이 어렵고 비효율적임.(가능은 하지만)
  • key 값으로 Notification의 이름과 userInfo를 서로 맞추기 때문에 컴파일 시 구독이 잘 되고 있는지, 올바르게 userInfo의 value를 받아오는지 체크가 불가능함.
  • 추적이 쉽지 않을 수 있음.
  • Notificaiton post 이후 정보를 받을 수 없음.
  • NSObject를 상속받는 객체에서만 사용이 가능함.
  • dealloc될 때 옵저버를 지워줘야 함.
  • 많은 value를 감지할 때는 많은 조건문이 필요.

 

Delegate

  • Protocol로 정의 (java의 interface => 규약)
  • Delegate 역할을 하려는 객체는 이 Protocol을 따르며 원형만 있던 메소드들의 구현을 함
  • 이렇게 세팅 후 이전 객체(SomeView)는 어떤 이벤트가 일어났을 시 delegate로 지정한 객체(SomeController)에 알려줄 수 있다.
    => 종속되어 동작하는 것이 아님. 독립적으로 떨어져 있음.
// 1) Delegate 프로토콜 선언
protocol SomeDelegate {
    func someFunction(someProperty: Int)
}

class SomeView: UIView {
    // 2) 순환 참조를 막기 위해 weak으로 delegate 프로퍼티를 가지고 있음
    weak var delegate: SomeDelegate?
    
    func someTapped(num: Int) {
        // 3) 이벤트가 일어날 시 delegate가 동작하게끔 함
        delegate?.someFunction(someProperty: num)
    }
}
// 4) Delegate 프로토콜을 따르도록 함
class SomeController: SomeDelegate {
    var view: SomeView?
    
    init() {
        view = SomeView()
        // 6) delegate를 자신으로 설정
        view?.delegate = self
        someFunction(someProperty: 0)
    }
    
    // 5) Delegate 프로토콜에 적힌 메소드 구현
    func someFunction(someProperty: Int) {
        print(someProperty)
    }
}

let someController = SomeController()
// prints 0

 

Notification

Notification Center라는 싱글턴 객체를 통해서 이벤트들의 발생 여부를 옵저버를 등록한 객체들에게 Notification을 post하는 방식으로 사용

// 1) Notification을 보내는 ViewController
class PostViewController: UIViewController {
    @IBOutlet var sendNotificationButton: UIButton!
    
    @IBAction func sendNotificationTapped(_ sender: UIButton) {
        guard let backgroundColor = view.backgroundColor else { return }
      
        // Notification에 object와 dictionary 형태의 userInfo를 같이 실어서 보낸다.
        NotificationCenter.default.post(name: Notification.Name("notification"), object: sendNotificationButton, userInfo: ["backgroundColor": backgroundColor])
    }
}

// 2) Notification을 받는 ViewController
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 옵저버를 추가해 구독이 가능하게끔 함
        NotificationCenter.default.addObserver(self, selector: #selector(notificationReceived(notification:)), name: Notification.Name("notification"), object: nil)
    }
    
    // iOS 9 이상이 아닐 경우에는 removeObserver를 해줘야 함
    deinit {
        NotificationCetner.default.removeObserver(self)
    }
    
    @objc func notificationReceived(notification: Notification) {
        // Notification에 담겨진 object와 userInfo를 얻어 처리 가능
        guard let notificationObject = notification.object as? UIButton else { return }
        print(notificationObject.titleLabel?.text ?? "Text is Empty")
        
        guard let notificationUserInfo = notification.userInfo as? [String: UIColor],
            let postViewBackgroundColor = notificationUserInfo["backgroundColor"] else { return }
        print(postViewBackgroundColor)
    }
}

 

Key Value Observing

메소드나 다른 액션에서 나타나는 것이 아니라 프로퍼티의 상태에 반응하는 형태

(Swift 4 전까지는 NSObject의 메소드인 observeValue(forKeyPath:change:context:)를 오버라이드하여 옵저버를 추가했으나 Swift4부터는 구독하고 싶은 프로퍼티에 observe()를 추가하여 클로저로 사용할 수 있게 하였다. 그러나 Swift 상에서는 didSet이나 willSet 같은 것으로 충분히 대체가 가능할 것 같아(동감) 굳이 써야하나 싶은 패턴인 것 같다.)

 

 

 

 

 

 

Ref.

https://medium.com/@Alpaca_iOSStudy/delegation-notification-%EA%B7%B8%EB%A6%AC%EA%B3%A0-kvo-82de909bd29

'iOS > iOS 기본기' 카테고리의 다른 글

Autolayout & Size classes 정의  (0) 2019.12.22
토큰 기반의 인증  (0) 2019.12.21
[iOS] Layout - Safe Area  (0) 2019.12.09
[iOS] frame vs. bounds  (0) 2019.12.09
[iOS] int vs NSInteger vs NSNumber  (0) 2019.12.05

iOS7 - UIViewController의 topLayoutGuide, bottomLayoutGudie property

어떤 content(status bar, navigation bar, toolbar, tab bar, etc) 에도 덮이지 않는 뷰를 그리기 위해서 제공

iOS 11에서 해당 property deprecated => Safe Area 소개함. (iPhoneX 대응으로 인해 left, right 정보도 필요해짐)

 

UIView

In iOS 11 the UIViewController topLayoutGuide and the bottomLayoutGuide properties have been replaced by the new safe area properties in UIView: => safeAreaInserts, safeAreaLayoutGuide

@available(iOS 11.0, *)
open var safeAreaInsets: UIEdgeInsets { get }
 // UIEdgeInserts - top, left, bottm, right : edge 크기

@available(iOS 11.0, *)
open var safeAreaLayoutGuide: UILayoutGuide { get }
// UILayoutGuide: A rectangular area that can interact with Auto Layout.
// bottomAnchor, heightAnchor, centerXAnchor, ...

방법 1: 뷰의 frame을 safe area에 맞추는 방법

 

topSubview.frame.origin.x = view.safeAreaInsets.left
topSubview.frame.origin.y = view.safeAreaInsets.top
topSubview.frame.size.width = view.bounds.width - view.safeAreaInsets.left - view.safeAreaInsets.right
topSubview.frame.size.height = 300
// or
bottomSubview.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
bottomSubview.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
bottomSubview.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
bottomSubview.heightAnchor.constraint(equalToConstant: 300).isActive = true

방법 2 - View안의 label frame을 맞추는 방법

label.frame = safeAreaLayoutGuide.layoutFrame
// or
label.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor).isActive = true
label.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor).isActive = true
label.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor).isActive = true

 

 

 

https://medium.com/rosberryapps/ios-safe-area-ca10e919526f

https://devmjun.github.io/archive/SafeArea_1

'iOS > iOS 기본기' 카테고리의 다른 글

토큰 기반의 인증  (0) 2019.12.21
[iOS] Delegate, Notification, KVO 비교 및 장단점 정리  (0) 2019.12.10
[iOS] frame vs. bounds  (0) 2019.12.09
[iOS] int vs NSInteger vs NSNumber  (0) 2019.12.05
[iOS] NSOperation vs. GCD  (0) 2019.11.29

Frame, Bounds는 CGRect 타입인 View의 Instance Property이다.
둘의 차이점에 대해 알아보자.

 

 

 

CGRect

- 사각형의 위치와 크기를 포함하는 구조체

- CGPoint - x, y 좌표, CGSize - width, height

 

 

 

Frame

The frame rectangle, which describes the view's location and size in its superview's coordinate system.

  • 상위뷰의 좌표 시스템
  • frame을 변경하면?
    자식 뷰의 위치도 변경된다 -> 자식 뷰의 frame은 변경되지 않았으므로
  • 언제 사용?
    UIView 위치나 크기를 설정하는 경우

Bounds

The bounds rectange, which describes the view's location and size in its own coordinate system.

  • 자신만의 좌표 시스템
  • 기본 좌표: (0, 0)
  • bounds의 origin을 변경한다는 것은?  곧, subView들이 화면상에서 drawing 되는 위치가 변경됨을 의미

    => subView들의 frame 값을 변화시키는 것이 아니다. 부모뷰 좌표축이 변하면서 subView가 그려져야 하는 위치가 달라졌기 때문
    ScrollView/TableView 등을 스크롤할 때, scrollView.bounds가 변하고, 그리하여 subView들이 그려지는 위치가 대표적인 예
    (subView들의 frame이 달라지는 게 아님)

    ex ) targetView.bounds.origin.x = 60; 
           targetView.bounds.origin.y = 50; 
           이라고 하면 targetView가 x축-> 60, y축-> 50으로 이동된 자식 뷰가 그려짐.!!!!!!!!!! 
  • 언제 사용?
    - View 내부에 그림을 그릴 때 (drawRect)
    - transformation 후, View의 크기를 알고 싶을 때
    - 하위 View를 정렬하는 것과 같이 내부적으로 변경하는 경우

 

 

 

Ref.

Frame과 bound의 차이(2/2) : https://zeddios.tistory.com/231

Frame과 bound의 차이(1/2) : https://zeddios.tistory.com/203

CGRect와 CGSize의 차이, 그리고 CGPoint: https://zeddios.tistory.com/201

'iOS > iOS 기본기' 카테고리의 다른 글

[iOS] Delegate, Notification, KVO 비교 및 장단점 정리  (0) 2019.12.10
[iOS] Layout - Safe Area  (0) 2019.12.09
[iOS] int vs NSInteger vs NSNumber  (0) 2019.12.05
[iOS] NSOperation vs. GCD  (0) 2019.11.29
[iOS] UIKit framework 계층도  (1) 2019.11.25

Autolayout을 왜 사용해야하나?

: 모든 기기와 아이패드의 멀티태스킹을 지원하기 위해 불가피해지게 되었음.

 

Auto Layout Engine이 어떻게 뷰를 그리는지 알아보자.

Auto layout은 두가지 input을 사용한다: 

1) View Constraint 2) App Screen size

 

 

 

WWDC 2015 Mysteries of Auto Layout, Part1

Layout Engine은 모든 constraints를 취하여 Alignment Rects를 계산하고, 그에 따라 실제로 우리의 뷰를 배치한다

1) 뷰의 사이즈 제약사항

2) 제약사항의 우선순위, 컨첸츠 우선순위 (content hugging, compression resistence)

3) 정렬 - 수평 정렬, 수직 정렬, baseline 정렬

 

Build the layout

자세하게 살펴보자.

1. Activate and Deactivate

Constraints find their own container

Adds constraints efficiently
Do not need to own all views

 

Changing Constraints

Never deactivate self.view.constraints

Keep references to constraints
Animate changing constraints with view animation

 

2. View Sizing - Sizing Constraints 

  • 특정 뷰는 intrinsicContentSize를 가지고 있음 (UILableView, UIImageView, ...)
  • Constraint는 View의 size를 정의함.
  • Self-Sizing View는 Constraint들로부터 온전한 사이즈를 결정함 (예: UITableViewCell height size)

 

3. Priorities - constraint priorities, content priorities

Summary

- Can help keep constraints from unsatisfiability => But look out for competing priorities!

- Results are more consistent

- Use content priorities to get to the right layout => Hugging priorities hug content, Compression resistance resists squishing

 

왜 이런 Ambiguity 현상이 일어날까?

- Not enough constraints

- 일치(equal)하거나 필요가 충족되지 않은(non-required) priorities

 

Constraint priorities

- Priorities go from 1–1000  (Required is 1000, DefaultHigh is 750, DefaultLow is 250)

- Highest priority wins

 

Content priorities

- 뷰의 컨텐츠를 처리하는 방법 

- By default, these are not set as required. (Content needs to be able to move a little bit)

     : Do not set as required

     : Can cause unsatisfiable constraints

- Equal priorities can cause ambiguity

- Types

  • Content hugging priorities

  • Compression resistance priorites
    : this is how much a view resists its content getting squished.

 

 

4. Alignment - horizontal alignment, vertical alignment, baseline alignment

Aligning Baselines

Use firstBaseline and lastBaseline

firstBaseline / lastBaseline

Leading and Trailing

- Use leading/trailing instead of left/right

- Helps with prep for localization

 

Alignment Rects

Alignment rects are important because it's what the engine actually calculates.

The engine takes all of your constraints, calculates the alignment rects, and uses them to actually layout your views.

 

- Usually (not always) same as frame

- Includes the critical content only

- Does not change when view is transformed

- Override alignmentRectInsets if needed

- Find out the calculated rects (Use Show Alignment Rectangles in Debug menu)

- Get using alignmentRectForFrame:

 

Finally!!!!

 

 

 

Content Hugging Priority vs. Content Compression Resistance Priority

Ref. https://m.blog.naver.com/PostView.nhn?blogId=jdub7138&logNo=220963551062&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

 

// view.setContentHuggingPriority(.required, for: .horizontal)

 

 

 

Ref.

https://developer.apple.com/videos/play/wwdc2015/218/

https://medium.com/@shantakokateit/how-auto-layout-engine-calculates-ui-components-frame-c617fc9c94ae

Properties

  1. Stored Properties
  2. Computed Properties
  3. Property Observers
  4. Global and Local Variables
  5. Type Properties

Properties

1. Stored Properties

  • A stored property is a constant or variable that is stored as part of an instance of a particular class or structure. 
  • Default property values
  • Assiging Constant properties during initalization (초기화 중에 할당되는 프로퍼티)

1-1) 상수 Structure 인스턴스의 stored property

  • If you create an instance of a structure and assign that instance to a constant, you cannot modify the instance’s properties, even if they were declared as variable properties:
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6 // this will report an error, even though firstValue is a variable property
  • 결론)
    Value type의 인스턴스를 상수로 생성하면, 모든 property는 변경할 수 없다.
    반대로, Reference type의 인스턴스를 constant로 생성하면 변경 가능하다.

1-2) Lazy Stored Properties:  인스턴스 초기화 -> 값 계산 -> 값 세팅

  • lazy stored property: 최초 사용될 때까지 초기 값이 계산되지 않는 프로퍼티
  • var keyword를 사용해야 함 => lazy stored property는 인스턴스 초기화가 완료될 때 까지 초기값을 가져올 수 없으므로 
    (let: 초기화가 완료되기 전에 값을 가져야 함.)

 

2. Computed Properties

  • Class, structure, enumeration은 computed property 정의 가능
  • 실제로 값을 저장하는 것이 아님
  • getter와 optional setter를 제공하여 다른 property의 값을 간접적으로 세팅할 수 있다.
struct CompactRect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            Point(x: origin.x + (size.width / 2),
                  y: origin.y + (size.height / 2))
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

 

3. Property Observers

  • property observer는 property의 값의 변화에 관찰하고 반응한다!(observe and respond)
  • property의 값이 세팅되는 매 순간마다 호출됨. (같은 값으로 세팅되더라도)
  • lazy stored property를 제외한 모든 property(stored, computed property)에 추가 가능
  • overriding된 상속받은 property에도 property observer를 추가할 수 있다.
  • observer 종류
    - willSet is called just before the value is stored.
    - didSet is called immediately after the new value is stored.
  • in-out 으로 observer를 가지는 property가 parameter로 전달되어도, willSet과 didSet observer는 항상 호출됨.
    => copy-in copy-out memory model이기 때문에!
class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps

 

 

4. Global and Local Variables

  • Global constants and variables are always computed lazily, in a similar manner to Lazy Stored Properties.
    Unlike lazy stored properties, global constants and variables do not need to be marked with the lazy modifier.

  • Local constants and variables are never computed lazily.

 

5. Type Properties

  • 클래스 변수
  • static keyword로 정의
struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    var currentLevel: Int = 0 {
        didSet {
            if currentLevel > AudioChannel.thresholdLevel {
                // cap the new audio level to the threshold level
                currentLevel = AudioChannel.thresholdLevel
            }
            if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                // store this as the new overall maximum input level
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}

var leftChannel = AudioChannel()
var rightChannel = AudioChannel()

leftChannel.currentLevel = 7
print(leftChannel.currentLevel)
// Prints "7"
print(AudioChannel.maxInputLevelForAllChannels)
// Prints "7"

rightChannel.currentLevel = 11
print(rightChannel.currentLevel)
// Prints "10"
print(AudioChannel.maxInputLevelForAllChannels)
// Prints "10"

 

 

 

 

Ref.

https://kka7.tistory.com/116?category=919617

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

'iOS > Swift' 카테고리의 다른 글

[Swift 5.2] Methods - Apple Documentation  (0) 2020.03.05
[Swift] ExpressibleByStringLiteral, CustomStringConvertible  (0) 2020.02.18
[Swift4.1] map, flapMap, compactMap  (0) 2019.12.11
[Swift5.1] Overview  (0) 2019.12.04
[Swift] if let vs. guard let  (0) 2019.11.29

볼때마다 헷갈려서 적어두고, Swift에서의 Integer의 개념에 대해서도 함께 살펴보자

 

 

세 가지는 모두 숫자를 나타내기 위한 데이터 타입이다!

int - C에서 왔고, primitive data type
NSInteger

- 현재 사용하고 있는 아키텍처(플랫폼)에 맞게 사이즈가 자동으로 설정되는 애플의 Foundation 프레임워크에 있는 특별한 primitive data type
- 실제로 int를 재정의함

NSNumber - Foundation 프레임워크의 NSNumber 클래스 인스턴스를 생성하는 것

 

즉, int와 NSInteger는 둘다 객체가 아니다!

 

'객체가 아니다' 란?

- 미리 정의된 사이즈가 있기 때문에 힙에 동적 메모리 할당을 하지 않는다.

- 스택에 생성되므로 포인터로 변수의 값을 접근하지 않아도 된다.

 

유사한 데이터타입
int, NSInteger, CGFloat, CGPoint, CGRect, 등

 

NSNumber를 사용하는 이유는?
체를 만드는 데 꼭 다른 객체를 사용하는 몇몇의 Cocoa 클래스들이 있기 때문(primitive type들은 사용할 수 없음)

ex) NSArray

 

 

Swift에서의 Integer

- Integers는 signed(positive, zero, negative)이거나 unsigned(positive, zero)임

- Swift provides signed and unsigned integers in 8, 16, 32, and 64 bit forms.

- UInt8, Int32, ...

Int

Swift provides an additional integer type, Int, which has the same size as the current platform’s native word size:

  • On a 32-bit platform, Int is the same size as Int32.
  • On a 64-bit platform, Int is the same size as Int64.
UInt

Swift also provides an unsigned integer type, UInt, which has the same size as the current platform’s native word size:

  • On a 32-bit platform, UInt is the same size as UInt32.
  • On a 64-bit platform, UInt is the same size as UInt64.

 

NOTE
Use UInt only when you specifically need an unsigned integer type with the same size as the platform’s native word size. If this isn’t the case, Int is preferred, even when the values to be stored are known to be nonnegative. => This aids code consistency and interoperability.

 

 

 

Ref.

https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html

https://beankhan.tistory.com/18

'iOS > iOS 기본기' 카테고리의 다른 글

[iOS] Layout - Safe Area  (0) 2019.12.09
[iOS] frame vs. bounds  (0) 2019.12.09
[iOS] NSOperation vs. GCD  (0) 2019.11.29
[iOS] UIKit framework 계층도  (1) 2019.11.25
[iOS] NSCopying protocol  (0) 2019.11.25

+ Recent posts