2016-08-25 4 views
1

방금 ​​ARC 자습서를 따라이 코드가 제공되었습니다.ARC와 정확히 작동하는 방법.

아래의 ViewController 클래스와 그 아래에 Vehicle 클래스가 있습니다.

내가 얻은 것은 ARC가 기본적으로 인스턴스화 된 클래스를 추적하고 그에 대한 메모리를 할당한다는 것입니다. 인스턴스에 대한 "강력한"참조가 작성되면 아크는 인스턴스에 대한 참조 수를 증가시킵니다. 모두가 nil로 설정되면 ARC는 인스턴스를 메모리에서 할당 해제합니다. 강사는 또한 모든 참조가 사용되지 않으면 메모리에서 할당을 해제합니다. 나는 그들이 "사용"되지 않는 부분을 잘 이해하지 못했기 때문에 코드가없는 다른 View Controller를 제공하는 버튼을 추가하기로 결정했습니다. 다음 뷰 컨트롤러로 이동하면 뷰 컨트롤러 1에서 참조가 호출되고 deinit가 사용되지 않고 메모리에서 할당이 해제된다는 것을 알았습니다. 이것은 사실이 아니었고 국장은 부름을받지 않았습니다. 그러므로, 나는 당신이 그것들을 무효로 설정하지 않는다면 참조가 메모리에 남아 있는지 궁금합니다.

질문 2 : 또한 질문에 대답하는 동안 또 다른 질문이 있습니다. ARC가 내가 본 문서 또는 튜토리얼의 모든 부분부터 클래스 인스턴스와 참조에 적용되는지 궁금합니다. 클래스 인스턴스 만 언급하는 것 같습니다. 예를 들어 var number = 2 var othernumber = number을 설정하면 "숫자"도 메모리에 저장되고 모든 숫자가 0이 될 때까지 할당이 취소됩니다. 이 경우에도 똑같은 질문이 적용됩니다. 메모리에서 할당 해제하는 유일한 방법은 모든 참조를 nil과 동일하게 설정하는 것입니다. 긴 질문에 대한 미안하지만, 메모리 개념에 아주 새로운 메신저.

import UIKit 

class ViewController: UIViewController { 


var ref1: Vehicle? 
var reference2: Vehicle? 
var ref3: Vehicle? 
var timer: NSTimer! 
var count = 0 
override func viewDidLoad() { 
    super.viewDidLoad() 

    ref1 = Vehicle(kind: "Car") 
    reference2 = ref1 
    ref3 = ref1 

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(tick), userInfo: nil, repeats: true) 


} 


func tick() { 
count++ 

    if count >= 3 { 
     ref3 = nil 
     reference2 = nil 



    } 

    if count == 5 { 
    ref1 = nil 


    } 


} 

}

class Vehicle { 

let type: String 


init(kind: String){ 
self.type = kind 
print("\(type) is being initialized") 
//when the class is instantiated, we get an initialization message. When class is deallocated, we get a deinit message. As in, all strong references are gone, we can deinitialize. 


} 
deinit { 
//class vehicle not in memory anymore as all strong references to it have been destroyed. This will be tested with segue as well. 
    print("\(type) is being deinitialized") 

}} 

답변

3
  1. "사용 된"용어입니다 혼란/(또는 기껏해야 부정확) 오해의 소지가. ARC를 사용하면 강건한 참조가 없거나 평범하고 단순해질 때까지 객체가 해제되지 않습니다. 만약 당신이 nil 그 모든 강력한 참조, 또는 그 강력한 참조 범위를 벗어난, 그 때 개체가 할당이 해제됩니다.

    그런데 scheduledTimerWithTimeInterval은 목표에 대한 강력한 참조를 설정한다는 점에 유의하십시오. 당신은 그 강한 참조를 해결하기 위해 타이머 invalidate해야합니다.

  2. ARC는 참조 유형 (즉, class 인스턴스)에만 적용됩니다. 값 유형 (예 : 숫자 유형 또는 struct 유형)에는 적용되지 않습니다. 따라서

    number을 참조하지 않습니다

    var number = 2 
    var othernumber = number 
    

    othernumber을 고려하십시오. 그것은 사본을 만든다. 값이 number과 같은 값이되는 것은 새로운 객체입니다. Swift 값 유형을 참조 유형과 차별화하는 토론은 WWDC 2015 Building Better Apps with Value Types을 참조하십시오. (그런데 복잡한 값 유형의 배후 메모리 관리는 실제로 단순한 값 유형보다 복잡하지만이 대화에는 실제로 관련이 없습니다.하지만 동영상에서 일부 자세히 설명합니다. 관심이 있습니다.)

+0

어떤 상황에서 강력한 참조가 "out of scope"가 될지에 대해 Rob에게 문의 해 주셔서 감사합니다. – slimboy

+0

또한 값 유형을 추측하고 있으며, 또한 메모리에 할당되고 할당이 취소됩니다. 프로그래머는 메모리 공간을 확보하기 위해 직접 할당을 해제해야합니까? – slimboy

+0

그걸 정리 해줘서 고마워, 지금 당장. – slimboy

1

이것은 큰 질문입니다.

ARC를 이해하려면 수동 참조 계산을 이해해야합니다.

참조 계산은 어떤 개체가 아직 사용되고 있고 할당을 해제 할 수 있는지 추적하는 방법입니다.

수동 참조 계산에서 개체의 보유 개수가 있습니다.

보유 수를 늘리려면 개체에 보관 메시지를 보내고 보유 수를 줄이려면 놓습니다. 오브젝트에 해제 메시지를 보내면 보유 수는 0으로 떨어지고 오브젝트는 할당 해제/해제됩니다.

"autorelease pool"에 개체를 추가하는 autorelease 메시지도 있습니다. 코드가 반환되고 이벤트 루프가 방문 될 때마다 autorelease 풀의 모든 객체는 autorelease 풀에있을 때마다 릴리스 메시지를받습니다. (하나의 객체에 하나 이상의 autorelease 메시지를 보낼 수 있지만 그것을 무시하십시오.) Autorelease는 특별한 것을하지 않으면 사라지는 임시 객체를 반환 할 때 유용합니다. 자동 반복 된 객체는 현재 호출 체인에서 사용되지만 아무도 그 코드를 유지하지 않으면 코드가 반환 될 때 해제됩니다.

참조 횟수가 1 인 개체가 생성되어 소유자에게 반환되며 소유주는 개체가 완료되면 개체에 릴리스 메시지를 보내야합니다.

수동 참조 계산에서는 메모리 관리 의도를 표현하기 위해 정확한 위치에 코드에 retain, release 및 autorelease 호출을 넣어야합니다. 오류가 발생하면 메모리 누수 또는 충돌이 발생합니다.

ARC는 위의 모든 메커니즘을 사용하지만 컴파일러는 코드를 분석하여 보유, 릴리스 및 자동 릴리스 호출을 삽입합니다. 또한 최소 유지/초과 호출을 최소 요구 사항까지 제거합니다.

ARC에서는 변수를 강하거나 약한 것으로 선언하고 나머지는 컴파일러에서 처리해야합니다. 여전히 몇 가지 문제가 있지만 대부분 메모리 관리에 대해 걱정할 필요가 없습니다.

강력한 변수에 개체를 저장하면 컴파일러에서 retain 호출을 생성합니다. strong 변수를 0으로 설정하면 컴파일러가 객체에 릴리스 메시지를 보냅니다.

가비지 수집과 달리 시스템을 중지 할 필요가 없으며 메모리에서 시간이 많이 소요되는 정리 정리를 수행합니다. 객체에 대한 참조가 없어지면 객체는 해제됩니다.