Skip to content

Latest commit

ย 

History

History
299 lines (218 loc) ยท 6.69 KB

ARC-Basic.md

File metadata and controls

299 lines (218 loc) ยท 6.69 KB

ARC Basic

class Person {
  let testCase: String
  init(testCase: String) {
    self.testCase = testCase
  }
  deinit {
    print("\(testCase) is being deinitialized")
  }
}

case 1. Allocation & Release

print("\n---------- [ Case 1 ] ----------\n")

var obj1: Person? = Person(testCase: "case1") //count 1
obj1 = nil //count 0

case 2. ์ฐธ์กฐ ์นด์šดํŠธ ์ฆ๊ฐ€

print("\n---------- [ Case 2 ] ----------\n")

var obj2: Person? = Person(testCase: "case2") //count 1
var countUp = obj2  //count2


obj2 = nil   //count 1
countUp = nil  //count 0

/*
 ---------- [ Case 2 ] ----------

 case2 is being deinitialized //์‚ฌ๋ผ์ง
 */

case 3. Collection ์— ์˜ํ•œ ์ฐธ์กฐ ์นด์šดํŠธ

print("\n---------- [ Case 3 ] ----------\n")

var obj3: Person? = Person(testCase: "case3") //count 1
var array = [obj3, obj3]  //count 3

obj3 = nil //count 2
array.remove(at: 0) //count 1
array.remove(at: 0) //count 0

case 4. ๊ฐ•ํ•œ ์ฐธ์กฐ, ์•ฝํ•œ ์ฐธ์กฐ

  • strong : ๊ธฐ๋ณธ๊ฐ’. ๊ฐ•ํ•œ ์ฐธ์กฐ. Reference Count 1 ์ฆ๊ฐ€
  • unowned : ๋ฏธ์†Œ์œ  ์ฐธ์กฐ. Count ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์Œ. ์ฐธ์กฐ ๊ฐ์ฒด ํ•ด์ œ ์‹œ์—๋„ ๊ธฐ์กด ํฌ์ธํ„ฐ ์ฃผ์†Œ ์œ ์ง€
  • weak : ์•ฝํ•œ ์ฐธ์กฐ. Count ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์Œ. ์ฐธ์กฐํ•˜๋˜ ๊ฐ์ฒด ํ•ด์ œ ์‹œ nil ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ
print("\n---------- [ Case 4 ] ----------\n")

var strongObj4 = Person(testCase: "case4") //count 1
print(strongObj4)

//weak var weakObj4 = Person(testCase: "case4") //weak -> count 0 // ๋งŒ๋“ค์ž๋งˆ์ž ๋ฐ”๋กœ ํŒŒ๊ดด nil
//print(weakObj4)

//unowned var unownedObj4 = Person(testCase: "case4") //์˜ค๋ฅ˜๋ฐœ์ƒ : count 0 -> ๋งŒ๋“ค์ž๋งˆ์ž ๋ฐ”๋กœ ํ•ด์ œ, ํ•˜์ง€๋งŒ, unowned๋Š” ์ฐธ์กฐ๊ฐ์ฒด ํ•ด์ œํ–ˆ์–ด๋„ ๊ธฐ์กด ํฌ์ธํ„ฐ์ฃผ์†”๋ฅด ์ฐธ์กฐํ•จ. ๊ทธ๋ž˜์„œ ์ ‘๊ทผ์‹œ ํ•ด๋‹น์ฃผ์†Œ๋กœ ์ ‘๊ทผํ–ˆ์„๋•Œ ์˜ค๋ฅ˜๋ฐœ์ƒ. ๊ธฐ์กดํฌ์ธํ„ฐ์— ๊ฐ’์ด ์—†์–ด์„œ ์˜ค๋ฅ˜.
//๋•Œ๋ฌธ์—, unowned์„ ์“ธ๋•Œ๋Š” ์ ˆ๋Œ€๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์„ ๋•Œ๋งŒ ์จ์•ผํ•จ.
//print(unownedObj4)

unowned. weak - let , var

Q.๋‹ค์Œ 4์ค„์˜ ์ฝ”๋“œ ์ค‘ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€?

unowned let unownedLet = strongObj4
unowned var unownedVar = strongObj4
weak let weakLet = strongObj4 //weak์€ nil. let์œผ๋กœ ํ•˜๊ฒŒ๋˜๋ฉด ๋ณ€์ˆ˜๊ฐ€ ๋ ์ˆ˜ ์—†์Œ. nil๋กœ ๋ฐ”๋€” ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ var ๋ฅผ ์จ์•ผํ•จ.
weak var weakVar = strongObj4
  • weak์€ ์˜ต์…”๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ• ๋•Œ๋Š” ๊ผญ ์˜ต์…”๋„์„ ๋ฒ—๊ธฐ๊ณ  ์‚ฌ์šฉ.

Q.unowned ์™€ weak ์˜ ํƒ€์ž…์€?

print("Unowned type: ", type(of: unownedVar))
//Unowned type:  Person
print("Weak type: ", type(of: weakVar))
//Weak type:  Optional<Person>

Scope

  • ์Šค์ฝ”ํ”„ ๋ฒ”์œ„์— ์˜ํ•œ ํ• ๋‹น ๋ฐ ํ•ด์ œ
class LocalScope {
  func doSomething() {}
  deinit {
    print("LocalScope is being deinitialized")
  }
}

class ClassProperty {
  func doSomething() {}
  deinit {
    print("ClassProperty is being deinitialized")
  }
}

class Application {
  var prop = ClassProperty()
  
  func allocateInstance() {
    let local = LocalScope() //count1
    local.doSomething()
  }//count 0 ๋ฉ”์†Œ๋“œ๊ฐ€ ๋๋‚ ๋•Œ.
  
  deinit {
    print("Application is being deinitialized")
  }
}

Q. ์•„๋ž˜์˜ ์ฝ”๋“œ ์‹คํ–‰ ์‹œ ์ถœ๋ ฅ๋˜๋Š” ๋ฉ”์‹œ์ง€๋Š”?

var app: Application? = Application()
app?.prop.doSomething()
app?.allocateInstance()

Q. ClassProperty ๊ฐ์ฒด์˜ deinit ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ์š”?

app = nil//์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง.
app?.prop = nil //ํ”„๋กœํผํ‹ฐ๋งŒ nil๋กœ ๋ฐ”๊พธ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Œ.

Strong Reference Cycles

class Person {
  var pet: Dog?
  func doSomething() {}
  deinit {
    print("Person is being deinitialized")
  }
}

class Dog {
  var owner: Person?
  func doSomething() {}
  deinit {
    print("Dog is being deinitialized")
  }
}



var giftbot: Person? = Person() //count1
var tory: Dog? = Dog() //count 1

giftbot?.pet = tory //Dog - count 2
tory?.owner = giftbot //Person - count 2

//์™œ ์•ˆ๋ ๊นŒ?
//giftbot = nil //Person - count 1
//tory = nil //Dog - count 1


//์ด๋ฏธ ์•ž์— nil์„ ์คฌ๊ธฐ ๋•Œ๋ฌธ์— ๋˜ nil์„ ์ค„ ์ˆ˜ ์—†์Œ
giftbot?.pet

Q.๋‘ ๊ฐ์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ• ๋‹น ํ•ด์ œํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”?

// ์ˆœ์„œ ์ฃผ์˜

giftbot?.pet = nil //() dog - count 1
tory?.owner = nil //() Person - count 1

giftbot = nil //nil //Person - count 0
tory = nil //nil  //Dog - count0

//์ˆœ์„œ๋ฐ”๋€Œ๋ฉด ๋ชจ๋‘ nil๋กœ ๋‚˜์˜ด.

//๋ฐ˜ํ™˜์ˆœํ™˜ ์ฐธ์กฐ.

Strong, Unowned, Weak

class Teacher {
  var student: Student?
  deinit {
    print("Teacher is being deinitialized")
  }
}

class Student {
  // strong, unowned, weak
  let teacher: Teacher //(strong)
//  unowned let teacher: Teacher //(unowned: ์ฐธ์กฐ์นด์šดํŠธ ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์Œ. )
//  weak var teacher: Teacher?
  
  init(teacher: Teacher) {
    self.teacher = teacher
  }
  deinit {
    print("Student is being deinitialized")
  }
}

var teacher: Teacher? = Teacher() // T- count 1
var student: Student? = Student(teacher: teacher!) // S- count 1, T - count 2.(unowned๋กœ ๋„ฃ์„ ๊ฒฝ์šฐ count 1)
teacher?.student = student


print("\n---------- [ teacher release ] ----------\n")
teacher?.student = nil //Unowned์™€ weak์„ ์ผ์„ ๊ฒฝ์šฐ๋Š” ํ•ด๋‹น ์ฝ”๋“œ ์ œ์™ธํ•˜๊ณ  ์•„๋ž˜๊ฒƒ (teacher = nil)๋งŒ์œผ๋กœ๋„ ํ•ด์ œ๋จ. 
teacher = nil //์ž๋™์œผ๋กœ ํ•ด์ œํ•˜๊ณ  ์‹ถ์–ด ! // T - count 0

print("\n---------- [ student release ] ----------\n")
student = nil //S - count 0
 1) strong  : ๋ช…์‹œ์ ์œผ๋กœ nil ๋Œ€์ž… ํ•„์š”. teacher?.student = nil
 2) unowned : ์ž๋™์œผ๋กœ deinit. nil ์ฒ˜๋ฆฌ ๋œ ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ ๋ฐœ์ƒ
 3) weak    : ์ž๋™์œผ๋กœ deinit. nil ์ฒ˜๋ฆฌ ๋œ ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ฉด nil ๋ฐ˜ํ™˜
import UIKit

final class MemoryViewController: UIViewController {
  
  final class Person {
    var apartment: Apartment?
    let name: String
    
    init(name: String) {
      self.name = name
    }
    deinit {
      print("\(name) is being deinitialized")
    }
  }
  
  final class Apartment {
    var tenant: Person?
    let unit: String
    
    init(unit: String) {
      self.unit = unit
    }
    deinit {
      print("Apartment \(unit) is being deinitialized")
    }
  }
  
  var person: Person? = Person(name: "James") //count 1
  var apartment: Apartment? = Apartment(unit: "3A") //count 1
  
  func loadClass() {
    person?.apartment = apartment
    apartment?.tenant = person
  }
  
  deinit {
    print("MemoryViewController is being deinitialized")
  }
}


var memoryVC: MemoryViewController? = MemoryViewController()
memoryVC?.loadClass()
memoryVC = nil
1. ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ ํ™•์ธ
2. ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด ์ฐธ์กฐ์นด์šดํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ”๋€Œ๋ฉด์„œ ์ž˜ ํ•ด๊ฒฐ์ด ๋˜์—ˆ๋Š”์ง€ ์ •๋ฆฌํ•˜๊ณ 
    ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ด๋–ค ๋ถ€๋ถ„์ด ๊ทธ๋Ÿฐ์ง€ ์•Œ์•„๋ณด๊ณ  ์ง์ ‘ ํ•ด๊ฒฐํ•ด ๋ณผ ๊ฒƒ