ARC로 또는 ARC로? 장단점은 무엇입니까? [닫은]


113

현재 작업중인 프로젝트의 대부분의 코드가 iOS 5.0 이전에 작성 되었기 때문에 아직 ARC를 사용하지 않았습니다.

나는 단지 궁금했다. 수동으로 유지 / 해제하지 않는 편리함이 ARC 사용의 '비용'을 능가 하는가? ARC에 대한 귀하의 경험은 무엇이며 추천 하시겠습니까?

그래서:

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

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

1
죄송합니다. Java 용어를 다른 곳에서 사용하고 있습니다. ARC를 사용하면 객체를 필요 이상으로 메모리에 보관 한 다음 얼마 후에 자동 해제 풀의 그룹으로 해제 할 수 있습니다. 내가 언급하는 Java의 가비지 수집과 유사하게 나중에 다른 객체와 함께 유지되고 해제되는 것은 이러한 효과입니다.
Simon Withington

3
@TenementFunster, 동일한 코드 (해제 호출 제외)에 대해 ARC는 비 ARC 코드보다 더 이상 객체를 보유합니다. 사실, 그것은 종종 당신이 가질 수있는 것보다 더 빨리 그것을 릴리스합니다. 다소 느리지 만 일반적인 패턴이 너무 빨라져서 성능에 미치는 영향을 덜어줍니다. 많은 일반적인 패턴 (예를 들어 자동 릴리스와 함께 반환 된 객체 유지)의 경우 문자 그대로 ARC가 자동으로 수행하는 것만 큼 빠르게 수동으로 작성할 수 없습니다.
Rob Napier 2012 년

1
가비지 수집과 관련하여 비슷한 질문에 대한 내 대답을 참조하십시오. Objective-C 자동 참조 계산과 가비지 수집의 차이점은 무엇입니까?
Brad Larson

답변:


147

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

이제 작은 단점에 대해 말씀 드리겠습니다.

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

  • Core Foundation 코드에 연결하는 데 몇 가지 (매우) 작은 복잡성이 있습니다. 아무것도 처리에 더 많은 합병증이 약간 있다는 것을 취급합니다 idA와 void*. C-arrays와 같은 id것은 올바르게 수행하기 위해 조금 더 생각해야 할 수 있습니다. ObjC의 멋진 처리 va_args도 문제를 일으킬 수 있습니다. ObjC 포인터의 수학과 관련된 대부분의 작업은 까다 롭습니다. 어쨌든 이것의 많은 것을 가져서는 안됩니다.

  • 당신은 넣을 수 없습니다 idA의 struct. 이것은 매우 드물지만 때로는 데이터를 압축하는 데 사용됩니다.

  • 올바른 KVC 이름 지정을 따르지 않고 ARC 및 비 ARC 코드를 혼합하면 메모리 문제가 발생합니다. ARC는 KVC 이름 지정을 사용하여 메모리 관리에 대한 결정을 내립니다. 모두 ARC 코드라면 양쪽에서 똑같은 "잘못된"작업을 수행하기 때문에 문제가되지 않습니다. 그러나 ARC / 비 ARC가 혼합되어 있으면 불일치가 있습니다.

  • ARC는 ObjC 예외가 발생하는 동안 메모리를 누수합니다. ObjC 예외는 프로그램 종료 시점에 매우 가까워 야합니다. 상당한 수의 ObjC 예외를 포착하는 경우이를 잘못 사용하고있는 것입니다. 이 문제는를 사용하여 수정할 수 -fobjc-arc-exceptions있지만 아래에 설명 된 패널티가 발생합니다.

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

  • ARC는 iPhoneOS 3 또는 Mac OS X 10.5 또는 이전 버전에서 전혀 작동하지 않습니다. (이로 인해 많은 프로젝트에서 ARC를 사용할 수 없습니다.)

  • __weak포인터는 iOS 4 또는 Mac OS X 10.6에서 제대로 작동하지 않습니다. 이는 부끄러운 일이지만 해결하기는 상당히 쉽습니다. __weak포인터는 훌륭하지만 ARC의 # 1 판매 포인트는 아닙니다.

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

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


편집하다

나는 "ARC를 사용하는 것이 Cocoa 메모리 관리 규칙을 아는 것을 대체 할 수 없다"는 몇 가지 주석을 보았습니다. 이것은 대부분 사실이지만 그 이유와 이유를 이해하는 것이 중요합니다. 첫째, 모든 코드가 ARC를 사용하고 Three Magic Words 를 위반하는 경우모든 곳에서 여전히 문제가 없습니다. 충격적이지만 거기에 있습니다. ARC는 유지하려는 의도가 아닌 일부 항목을 보유 할 수 있지만 해당 항목도 릴리스하므로 문제가되지 않습니다. 오늘 Cocoa에서 새 수업을 가르치고 있다면 실제 메모리 관리 규칙에 대해 5 분 이상을 쓰지 않을 것이며 KVC 이름 지정에 대해 논의 할 때 메모리 관리 이름 지정 규칙 만 언급했을 것입니다. ARC를 사용하면 메모리 관리 규칙을 전혀 배우지 않고도 실제로 괜찮은 초보 프로그래머가 될 수 있다고 믿습니다.

그러나 당신은 괜찮은 중급 프로그래머가 될 수 없습니다. Core Foundation과 올바르게 연결하려면 규칙을 알아야하며 모든 중급 프로그래머는 어느 시점에서 CF를 처리해야합니다. 그리고 혼합 ARC / MRC 코드에 대한 규칙을 알아야합니다. 그리고 당신은 (KVO를 올바르게 수행해야하는) void*포인터로 엉망이 될 때 규칙을 알아야합니다 id. 그리고 블록 ... 글쎄, 블록 메모리 관리는 이상합니다.

그래서 내 요점은 기본 메모리 관리가 여전히 중요하지만 새로운 프로그래머를위한 규칙을 설명하고 재 작성하는 데 상당한 시간을 소비했던 곳에서 ARC를 사용하면 더 고급 주제가되고 있습니다. 나는 새로운 개발자가 .NET에 대한 기본 호출로 머리를 채우는 것보다 객체 그래프 측면에서 생각하게 만들고 싶습니다 objc_retain().


3
매우 조심해야 할 한 가지는 (비 ARC에서도 마찬가지지만 ARC에서는 더 그렇습니다. 지금은 그렇게 보이지 않기 때문에) 유지주기입니다. 여기 내 조언은 1) objc 블록을 인스턴스 변수로 저장하는 경우, 그것이 ivar 인 객체를 간접적으로도 캡처 할 수 있는지 오랫동안 자세히 살펴보십시오. 2) 개체 그래프를 그냥 두는 것이 아니라 실제로 디자인하십시오. 당신은 있어야 당신이 좋은 코드를 작성하려면 무엇을 소유 한 것을 알고있다. 3) 힙샷 사용 : friday.com/bbum/2010/10/17/…
Catfish_Man

1
@Catfish_Man 모든 좋은 점. 고정 루프는 항상 문제였습니다. Apple의 새로운 조언은 # 2에서 말한 것과 똑같습니다. 유지하고 해제하는 것보다 객체 그래프에 대해 생각할 필요가 있습니다. # 1은 블록에 대한 심각한 문제이며 블록이 혼합 된 축복이라고 생각하는 몇 가지 이유 중 하나는 신중하게 접근해야합니다.
Rob Napier 2012 년

2
언급되지 않은 심각한 단점이 하나 있습니다. 교차 호환성입니다. 크로스 플랫폼 프로그래밍으로 알려진 황무지에 직면 한 용감하고 어리석은 영혼들에게 ARC는 적어도 GNU가 ObjC 런타임 및 컴파일러 기능을 다시 확장 할 때까지는 옵션이 아닙니다.
토끼

2
iOS 3.x 장치를 지원해야하는 경우를 제외하고 ARC를 사용할 수 있습니다. BTW, 전환을 수행하려면 Xcode를 사용해야합니다 (Edit> Refactor> Convert to Objective-C ARC). 프로세스 중에 Xcode는 코드가 작동하는지 확인하고 해당 설계 지침을 위반하는 코드를 파악하기 위해 많은 유효성 검사를 수행합니다.
ZhangChn

1
우수 .. 지적 대답. 그것은 나에게서 100 번째입니다. 한 세기를위한 Congrates)
아제 샤르마

20

내 것보다 더 나은, 더 기술적 인 답변이 올 것이다.

  • ARC! = 가비지 콜렉션. 런타임 패널티는 없으며 컴파일 타임에 수행됩니다.
  • ARC 또한! = 귀하의 의견에서 제안한대로 모든 것을 자동 해제합니다. 문서 읽기
  • 그것은 당신이 얼마나 설명서를 참조 관리 실현되면 끝내 일을
  • 그걸 써!
  • 한 가지 단점은 오래된 비 아크 코드를 유지하는 것이 갑자기 매우 지루해집니다.

그렇기 때문에 지금까지 사용하지 않은 것입니다. 기존의 상당한 양의 코드를 사용하여 변환 할 수 있을지 모르겠습니다. 다음 프로젝트에서 시도해 보겠습니다. 답변 : 감사합니다
사이먼 딩턴

오래된 코드를 유지하는 것이 더 어려워지는 것이 아니라 기대가 바뀌었기 때문입니다. 따라서 삶을 더 쉽게 만드는 데 ARC를 비난하는 것은 실제로 공정하지 않습니다. Xcode를 사용하면 준비가되었을 때 이전 코드를 ARC로 쉽게 변환 할 수 있지만, 이전 iOS 버전을 지원해야하는 경우에는 분명히 사용할 수 없습니다.
Caleb

1
@Caleb 나는 ARC를 비난하지 않았습니다. 그것은 내가 지금까지 본 유일한 단점입니다-단일 프로젝트의 공간에서 나를 썩게 만들었습니다.
jrturton

네; 나는 그것을 문제로 나열하지 않았지만 코드베이스 사이를 전환해야 할 때 메모리 관리 연습에서 벗어나는 작은 문제가 있습니다. 내 프로젝트 중 일부는 10.4에서 실행되므로 여전히 많은 Objective-C 1.0 작업을 수행합니다 (ARC는 말할 것도없고 @synthesize도 없음). 하지만 모드 전환에 익숙해집니다.
Rob Napier 2012 년

@jrturton 나는 ARC가하는 일을 이해하지 못할 수있는 OP와 미래의 독자들을 위해 글을 썼다는 것을 더 분명하게해야했습니다. 나는 당신이 의미하는 바를 정확히 알고 있습니다. ARC와 비 ARC 코드를 혼합하면 문제가 발생한다는 잘못된 결론을 누구에게도 원하지 않았습니다.
Caleb

16

ARC는 프로젝트에 얼마나 많은 이점을 가져올 수 있습니까?

이점은 일반적인 메모리 관리 실수로부터 상당한 수준의 보호입니다. 객체 해제 실패로 인한 누수 및 객체 유지 실패 또는 조기 해제로 인한 충돌을 크게 줄여야합니다. 참조를 강함 또는 약함으로 분류하고 유지주기를 피하는 등의 작업을 수행하려면 참조 카운트 메모리 모델을 이해해야합니다.

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

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

ARC를 사용해 왔으며 그렇다면 지금까지 어떻게 찾았습니까?

계산을 참조하는 데 익숙하다면 약간 당황 스럽지만, 익숙해 져 컴파일러가 실제로 올바른 일을 할 것이라는 것을 신뢰하는 법을 배우는 문제 일뿐입니다. Objective-C 2.0과 함께 제공되는 속성 변경이 계속되는 것처럼 느껴지며, 이는 메모리 관리를 단순화하는 또 다른 큰 단계였습니다. 수동 메모리 관리 호출이 없으면 코드가 조금 더 짧아지고 읽기 쉬워집니다.

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


1
내가 말했던 더 나은 대답이 있습니다!
jrturton

1
네, 좋은 대답입니다. 그렇다면 ARC가 작동한다는 것을 신뢰하는 법을 배워야하는 것 외에는 실제로 ARC의 단점이 없습니까? 그럴 경우에는 너무 좋은 것 같나요?
Simon Withington

4

ARC는 좋은 아이디어라고 생각합니다. GC에 비해 케이크도 먹고 먹을 수 있습니다. 나는 MRC가 모든 사람이 혜택을받을 수있는 메모리 관리에 대해 귀중한 '훈련'을 부과한다고 믿는 경향이 있습니다. 그러나 나는 또한 알고 있어야 할 실제 문제가 객체 소유권과 객체 그래프 (많은 사람들이 지적했듯이)이며 저수준 참조 카운트 자체가 아니라는 데 동의합니다.

결론적으로, ARC는 기억에 대해 신경 쓰지 않는 자유 패스가 아닙니다. 인간이 스트레스를 유발하고 오류가 발생하기 쉬운 반복 작업을 피할 수 있도록 도와주는 도구입니다. 따라서 머신 (이 경우 컴파일러)에 더 잘 위임됩니다.

즉, 저는 개인적으로 일종의 장인이며 아직 전환을하지 않았습니다. 방금 Git을 사용하기 시작했습니다 ...

업데이트 : 그래서 전체 게임을 마이그레이션하고 gl 라이브러리를 포함했으며 지금까지 문제가 없습니다 (Xcode 4.2의 마이그레이션 도우미 제외). 새 프로젝트를 시작하는 경우 시작하십시오.


2

나는 몇 가지 (분명히 작은) 프로젝트에서 그것을 사용했으며 성능과 신뢰성 측면에서 좋은 경험 만 가지고 있습니다.

한 가지주의해야 할 점은 UI를 직접 코딩하는 경우 참조 루프를 발생시키지 않도록 약한 참조의 do : s 및 do n't : s를 배워야한다는 것입니다. 디자이너는이를 잘 수행하는 경향이 있습니다. GUI를 사용하여 설정하면 자동으로.


2

내가 만난 유일한 단점은 CoreFoundation 함수와 데이터가 많은 라이브러리를 사용하는 경우입니다. MRC에서 당신은 사용에 대해 걱정할 필요가 없었다 CFStringRef대신을 NSString*. ARC에서는 두 가지가 상호 작용하는 방식을 지정해야합니다 (기본 브리지? CoreFoundation 개체를 해제하고 ARC로 이동? Cocoa 개체를 +1 CoreFoundation 유지 개체로 만드시겠습니까?) 또한 OS X에서는 64에서만 사용할 수 있습니다. 비트 코드 (그 주위에서 작동하는 헤더가 있지만 ...).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.