2012-01-06 1 views
109

저는 아직 ARC를 사용하지 않았습니다. 왜냐하면 제가 현재 작업하고있는 프로젝트의 대부분의 코드가 iOS 5.0 이전 버전으로 작성 되었기 때문입니다.ARC하려면 ​​또는 ARC하지 않으시겠습니까? 장단점은 무엇입니까?

나는 궁금한 점이있다. 수동으로 유지/해제하지 않고 (결과적으로 더 안정적인 코드가 제공 될 것인가?) ARC를 사용하는 데 '비용'보다 중요한 점은 무엇일까? ARC에 대한 귀하의 경험은 무엇입니까?

그래서 :

  • ARC 프로젝트에 얼마나 많은 이익을 가져올 수있다?
  • ARC는 Java의 가비지 수집과 같은 비용이 있습니까?
  • ARC를 사용 해본 적이 있습니까? 그렇다면 지금까지 어떻게 찾았습니까? 나보다
+0

ipad/ios에는 가비지 콜렉션이 없습니다. OS X에 대해 이야기하고 있습니까? – dasblinkenlight

+1

제 사과, 자바 용어를 비효율적으로 사용하고 있습니다. 즉, ARC를 사용하면 객체를 필요한 시간보다 오래 메모리에 보관 한 다음 나중에 자동 릴리스 풀에 그룹으로 릴리스 할 수 있습니다. 나중에 참조 할 Java 가비지 콜렉션과 마찬가지로 나중에 다른 오브젝트와 함께 보관 및 릴리스되는 효과입니다. –

+3

@TenementFunster, 동일한 코드 (릴리스 호출을 뺀)에 대해 ARC는 객체를 ARC 이외의 코드로 처리하지 않습니다. 실제로, 그것은 종종 당신이 가지고있는 것보다 빨리 풀어 낼 것입니다. 아주 느린 것은 많지 않지만 일반적인 패턴을 너무 빨리 불러 일으켜 성능에 미치는 영향을 줄였습니다. 많은 일반적인 패턴들 (예를 들어 autorelease로 반환 된 객체를 유지함)의 경우, ARC가 자동으로 수행하는 것처럼 수동으로 작성할 수 없습니다. –

답변

145

단점은 없습니다. 그걸 써. 오늘 해. 이전 코드보다 빠릅니다. 이전 코드보다 안전합니다. 이전 코드보다 쉽습니다. 쓰레기 수거가 아닙니다. GC 런타임 오버 헤드가 없습니다. 컴파일러는 어쨌든 가지고 있어야하는 모든 장소에 보유 및 릴리스를 삽입합니다. 그러나 그것은 당신보다 더 똑똑하고 실제로 필요하지 않은 것들을 최적화 할 수 있습니다 (마치 루프 풀기, 일시 변수, 인라인 함수 등을 제거하는 것과 같습니다)

이제는 작은 단점 :

  • 오랫동안 ObjC 개발자 인 경우 ARC 코드가 표시되면 약 1 주일 동안 트 위치합니다. 당신은 매우 빨리 이것을 극복 할 것입니다.

  • 코어 파운데이션 코드에 브리징 할 때 약간의 (매우) 약간의 복잡성이 있습니다. idvoid*으로 처리하는 경우에는 약간 더 복잡합니다. id의 C- 배열과 같은 것들은 올바르게하려고 생각할 수 있습니다. ObjC va_args의 멋진 처리로 인해 문제가 발생할 수도 있습니다. ObjC 포인터에서 수학과 관련된 대부분의 일은 까다 롭습니다. 어쨌든이 점을 많이 가져서는 안됩니다.

  • idstruct에 넣을 수 없습니다. 이것은 매우 드문 경우이지만 때로는 데이터를 압축하는 데 사용됩니다.

  • 올바른 KVC 명명법을 따르지 않았고 ARC 및 비 ARC 코드를 혼합 한 경우 메모리 문제가 발생합니다. ARC는 KVC 이름 지정을 사용하여 메모리 관리에 대한 결정을 내립니다. 모든 ARC 코드라면 양쪽 모두 똑같은 "잘못된"일을하기 때문에 중요하지 않습니다. 그러나 ARC/비 ARC가 혼합 된 경우 불일치가 발생합니다.

  • ARC는 ObjC 예외가 throw되는 동안 메모리가 누출됩니다. ObjC 예외는 프로그램 종료까지 매우 가까워 야합니다. 상당한 수의 ObjC 예외를 잡으면 잘못 사용하고있는 것입니다. 이 문제는 -fobjc-arc-exceptions을 사용하여 고칠 수 있지만 아래에 설명 된 처벌이 발생합니다.

  • ARC는 ObjC++ 코드에서 ObjC 또는 C++ 예외가 throw되는 동안 메모리가 누출되지 않지만 시간 및 공간 성능을 모두 희생합니다. 이것은 ObjC++의 사용을 최소화해야하는 이유 중 하나입니다.

  • ARC는 iPhoneOS 3 또는 Mac OS X 10.5 이전에서는 전혀 작동하지 않습니다. (이로 인해 많은 프로젝트에서 ARC를 사용할 수 없게되었습니다.) iOS 4 또는 Mac OS X 10.6에서는 포인터가 올바르게 작동하지 않지만 문제는 간단합니다. __weak 포인터는 훌륭하지만 ARC의 판매 포인트가 아닙니다.

코드의 95 % 이상에 대해 ARC는 훌륭하고 피할 수있는 이유가 전혀 없습니다 (OS 버전 제한을 처리 할 수있는 경우). ARC가 아닌 코드의 경우 파일별로 -fno-objc-arc을 전달할 수 있습니다. Xcode는 불행히도 실제로는해야 할 일보다 훨씬 더 어렵게 만듭니다. 이것을 단순화하기 위해 비 -ARC 코드를 별도의 xcodeproj로 옮겨야합니다.

결론적으로 가능한 한 빨리 ARC로 전환하고 되돌아 보지 마십시오.


내가의 라인을 따라 코멘트 몇 본 적이

편집 "을 사용하여 ARC는 코코아 메모리 관리 규칙을 알고을 대신 할 수 없습니다." 이것은 대부분 사실이지만, 이유와 이유를 이해하는 것이 중요합니다. 첫째, 모든 코드가 ARC를 사용하고 Three Magic Words을 위반하는 경우에도 아무런 문제가 없습니다. 놀래키지만, 거기에 당신이 간다. ARC는 귀하가 보유해야한다는 것을 의미하지는 않지만 유지할 수있는 몇 가지 사항을 보유 할 수 있습니다. 오늘 코코아에서 새로운 수업을 가르치고 있다면, 실제 메모리 관리 규칙에 5 분 이상을 소비하지 않을 것입니다. KVC 이름 지정에 대해 논의하면서 메모리 관리 명명 규칙 만 언급 할 것입니다. ARC를 사용하면 실제로 메모리 관리 규칙을 전혀 배우지 않으면서도 훌륭한 프로그래머가 될 수 있다고 생각합니다.

그러나 중간 수준의 프로그래머가 될 수는 없습니다. Core Foundation과 올바르게 연결하기 위해서는 규칙을 알아야하며 모든 중간 프로그래머는 어느 시점에서 CF를 처리해야합니다. 그리고 혼합 ARC/MRC 코드에 대한 규칙을 알아야합니다. 그리고 void* 포인터를 id (정확하게 KVO를 수행해야하는 경우)으로 뒤범벅 할 때 규칙을 알아야합니다. 블록은 ... 음, 블록 메모리 관리가 이상합니다.

저의 요점은 기본 메모리 관리가 여전히 중요하다는 것입니다.하지만 ARC를 사용하여 새로운 프로그래머를위한 규칙을 설명하고 재 작성하는 데 많은 시간을 소비 했었지만 ARC는보다 고급 주제가되었습니다. 차라리 새 개발자가 objc_retain()이라는 기본 호출을 사용하여 머리를 채우는 대신 오브젝트 그래프로 생각하게 할 수 있습니다.

+0

Rob을 모두 입력 해 주셔서 고마워요. 사람들이 여기에서 쓴 모든 것을 읽은 후, 가장 큰 장애물은 컴파일러가 걱정할 필요가 있다고 생각하는 초기의 불신이 될 것이고, ret를 입력 할 때마다 손을 뻗은 후 손이 아플 수 있다고 생각합니다. - (탭) 또는 rel- (탭)! –

+3

매우주의해야 할 한 가지는 (ARC가 아닌 경우에도 ARC에서는 보이지 않기 때문에) 현재주기가 유지됩니다. 내 조언은 여기에 1) 인스턴스 변수로 objc 블록을 저장하는 경우, 간접적으로 심지어 ivar 개체를 캡처 할 수 있는지 확인하기 위해 긴 시간을 들여다보십시오. 2) 실제 그래프를 디자인하는 것이 아니라 실제로 그래프를 디자인하십시오. 좋은 코드를 작성하려면 무엇을 소유하고 있는지를 알아야합니다. 3) 힙샷 사용 : http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory -growth/ –

+1

@Catfish_Man 좋은 점. 유지 루프는 항상 문제가되어 왔습니다. Apple의 새로운 조언은 # 2에서와 똑같습니다. 우리는 유지하고 해제하기보다는 객체 그래프에 대해 생각할 필요가 있습니다. # 1은 블록에 심각한 문제입니다. 여러 가지 이유 중 하나는 조심스럽게 접근해야하는 혼합 된 축복을 차단한다는 것입니다. –

20

더 나은, 더 기술적 인 답변이 올하지만, 여기에 간다됩니다!

  • ARC = 가비지 수집을. 실행 시간 패널티가 없으며 컴파일 타임에 완료됩니다.
  • ARC 또한! = 귀하의 의견에 제안하는대로 모든 것을 자동으로 해제합니다. 읽기 docs
  • 당신이 훨씬 매뉴얼 참조 관리 당신에게 이 그것을 사용
  • 을하고 얼마나 실현하면 그것은 최고입니다!
  • 단점 - 갑자기 오래된 코드를 유지하는 것은 매우 지루합니다.
+0

그래, 그게 내가 지금까지 사용하지 않은 이유 야. 나는 우리의 상당량의 사전 검사를 통과 할 수 있을지 확신하지 못한다. 그것을 변환하는 기존 코드 ... 나는 확실히 다음 프로젝트를 시도해 볼 것이다. 답해 주셔서 감사합니다 :) –

+0

오래된 코드를 유지하는 것이 더 어려워지는 것은 아닙니다. 기대치가 바뀌 었습니다. 따라서 삶을 더 편하게 해주는 ARC를 비난하는 것이 적절하지 않습니다. Xcode를 사용하면 이전 코드를 ARC로 쉽게 변환 할 수 있지만 이전 iOS 버전을 계속 지원해야하는 경우에는 사용할 수 없습니다. – Caleb

+1

@Caleb ARC를 비난 한 것이 아니라, 지금까지 본 유일한 단점입니다. 하나의 프로젝트 공간에서 부패했습니다. – jrturton

2

저는 (두드러지게 작은) 몇 가지 프로젝트에서이 프로젝트를 사용했으며 성능과 안정성면에서 모두 좋은 경험을했습니다.

작은주의 사항은 당신이 할 일이 무엇인지 배우는 것입니다 : 당신이 혼자서 UI를 코딩 할 때 참조 루프를 발생시키지 않는 약한 참조의 경우, 디자이너는 GUI를 사용하여 GUI를 설정하면 자동으로 잘 수행됩니다.

16

ARC는 프로젝트에 어느 정도의 이점을 줄 수 있습니까?

이점은 일반적인 메모리 관리 실수로 인한 상당한 수준의 보호입니다. 물체를 놓치지 않아서 누출되거나 물체를 유지하지 못하거나 조기에 손을 떼기 때문에 크래시가 현저하게 감소해야합니다. 참조 계산 메모리 모델을 이해해야하므로 참조를 강하거나 약한 것으로 분류하고 유지주기를 피할 수 있습니다.

가비지 수집은 실제로 '비용'이 얼마입니까?

iOS에는 가비지 콜렉션이 없습니다. ARC는 개체를 수동으로 유지하거나 해제 할 필요가 없다는 점에서 GC와 유사합니다. 가비지 컬렉터가 없다는 점에서 GC와는 다릅니다. retain/release 모델은 여전히 ​​적용됩니다. 컴파일러가 컴파일 할 때 적절한 메모리 관리 호출을 코드에 삽입하는 것입니다.

ARC를 사용 해본 적이 있습니까? 그렇다면 지금까지 어떻게 찾았습니까?

계산을 참조하는 데 익숙하다면 다소 당황 스럽겠지만 실제로 익숙해지고 컴파일러가 실제로 올바른 작업을 수행 할 것이라는 것을 신뢰하는 것이 중요합니다. Objective-C 2.0과 함께 제공되는 속성을 계속 변경 한 것처럼 느껴졌습니다. Objective-C 2.0은 메모리 관리를 단순화하는 또 다른 큰 단계였습니다. 수동 메모리 관리 호출이 없으면 코드가 조금 더 짧아지고 읽기 쉽습니다.

ARC의 유일한 문제는 이전 버전의 iOS에서는 지원되지 않기 때문에 채택하기 전에 고려해야한다는 것입니다.

+1

더 나은 대답이 있습니다. – jrturton

+1

네, 좋은 대답입니다. ARC가 작동한다는 것을 신뢰하는 법을 배우는 것 외에 ARC에는 아무런 결점이 없습니다. 이 경우 사실이 되기에는 너무 좋은 것 같습니까? –

4

ARC는 좋은 아이디어라고 생각합니다. GC와 비교하면 케이크를 먹을 수 있습니다. 저는 MRC가 모든 사람들이 갖는 혜택을 누릴 수있는 소중한 '규율'을 메모리 관리에 부과한다고 생각하는 경향이 있습니다. 그러나 실제로 알고 있어야 할 실제 문제는 개체 소유권 및 개체 그래프 (많은 사람들이 지적했듯이)이며 저급 참조 횟수 자체가 아니라는 데 동의합니다.

결론 : ARC는 메모리에 대해 신경 쓸 필요가없는 자유로운 통과입니다. 이것은 인간이 반복적 인 작업을 피하도록 도와주는 도구로서 스트레스를 유발하고 오류가 발생하기 쉽기 때문에 기계 (이 경우 컴파일러)에 더 잘 위임됩니다.

나는 개인적으로 친절한 장인이며 아직 전환을하지 않았다고 말했다. 방금 Git을 사용하기 시작했습니다 ...

업데이트 : 그래서 전체 게임 (gl 라이브러리 포함)을 마이그레이션 했으므로 문제가 없습니다 (Xcode 4.2의 마이그레이션 비서를 제외하고). 당신이 새로운 프로젝트를 시작한다면, 그것을 위해 가십시오.

2

CoreFoundation 함수 및 데이터가 많은 라이브러리를 사용하는 경우에만 부딪혔습니다. MRC에서는 NSString* 대신 CFStringRef을 사용하는 것에 대해 걱정할 필요가 없었습니다.ARC에서는 두 객체가 상호 작용하는 방식을 지정해야합니다 (기본 Bridge? CoreFoundation 객체를 릴리스하고 ARC로 이동? 코코아 객체를 +1 CoreFoundation 유지 객체로 만드시겠습니까?) 또한 OS X에서는 64 비트 객체에서만 사용할 수 있습니다. 비트 코드 (그 주위에 작동하는 헤더가 있지만 ...).