2012-02-22 4 views
3

저는 iPad (전용) 앱으로 작업 중이며 이상한 문제를 발견했습니다. 응용 프로그램은 iPad 1에서 메모리 경고 후에 종료되지만 iPad 2에서는 정상적으로 작동합니다. ARC를 사용하고 iOS 5를 타겟팅합니다. 닙 (nib)을 사용하고 대부분의 자산이 UIImageViews를 사용하여 표시됩니다. 또한 몇백 개의 버튼과 제스처 인식기가 있습니다 ... ARC에서 WWDC11 비디오 (세션 323 및 322)를 다시 보았고 특별한 작업을 수행하지 않는 것 같습니다.ARC : 메모리가 다시 확보되지 않습니까?

응용 프로그램은 UIImage를 많이 사용하며 UIImage를 사용하여 많은 애니메이션을 만들고 있습니다. 그러나 imageNamed 호출 대신 initWithContentsOfFile 생성자를 사용하고 있습니다. 시스템에서 이미지를 캐시하지 못하게하려고합니다.

또한 사운드 효과를 예약하고보기를 애니메이션화하기 위해 GCD를 사용하고 있습니다. 나는 항상 메인 스레드에서 이것을하고있다.

응용 프로그램은 스택에 UIViewController를 두 개 이상 가지지 않는 UINavigationController를 사용합니다. didReceiveMemoryWarning이 현재보기 컨트롤러에서만 호출되기 때문에 이것이 사실임을 확인할 수 있습니다 (호출을 로깅합니다).

내가 알지 못하는 점은 계측기가 할당 및 VM 추적기 도구에서 높은 수를보고하는 것입니다 (보기 컨트롤러가 할당 취소되지 않는 것처럼). Allocations 장비는 하나의보기 컨트롤러에서 다른보기 컨트롤러로 이동할 때 작은 방울을 표시하지만 VM 추적기 인스트루먼트는 똑같은 작업을 수행 할 때 더티 크기가 떨어지지 않는 것을 보여줍니다. 결국 앱은 너무 많은 메모리를 사용하여 종료됩니다 (iPad 1에서). iPad 2에서 메모리 경고를 받으면 앱이 종료되지 않습니다.

내 이미지, 소리 또는보기가 손상되지 않고 메모리가 재생 된 것처럼 느껴집니다 ... 내 개체 계층 구조는 매우 기본적이고 어떤 종류의 유지 사이클도 있어서는 안됩니다. 나는 심지어 단순한 대의원도 없다 ...

의견이 있으십니까? 난 정말 iPad 2 이상에서만이 응용 프로그램을 공개하고 싶지 않아요 ... 그것은 아이를위한 애플 리케이션과 그것은 핏빛 것입니다 ... 나는 내가 뭔가 잘못하고있는 걸 배우는 것이 너무 행복 할거야 , 정말 ...

건배, 닉이 응용 프로그램이 될 수있는 최선입니다 있는지 확인하려면로

+0

간단한 설명 : 악기를 사용하여 누출을 검색하는 데 많은 시간을 투자했지만 아무 것도없는 것처럼 보입니다. 게다가, 만약에 iPad 2가 충돌하고 결국 불 태울 거라고 생각했는데, 그럴 수는 없지만 ... – nicktmro

답변

1

내 자신의 질문에 답하는 것과 같지만 미래의 Google 직원에게 도움이 될 수 있다고 생각했습니다. 내 자신의 UIImage 기반 애니메이션을 구현하고 더 이상 animationImages 속성을 사용하지 않습니다. 더 이상 메모리에 모든 이미지를 저장할 필요가 없으며 타이머를 사용하여 필요에 따라로드합니다.

실제로 사용자 지정 애니메이션을 롤아웃하면 콜백 및보다 강력한 사용자 지정 옵션을 사용할 수 있기 때문에 유용하다고 생각합니다.

일단 내가 만족하면 GitHub에 클래스를 게시 할 준비가되었다고 느낍니다.

+0

코드를 게시 할 수 있습니까? – chrisallick

1

, 말할 때 특정 nil에 속성을 설정하여 객체를 '최적화'할 수있는 방법이 있습니다 이제는 dealloc 메소드를 쓸 수는 없지만, ARC가 아닌 세계에서 '보유'(즉, strong)와 같은 작업을 수행하는 self.object = nil (해당되는 경우)을 수행 할 수 있습니다. 재산 :

- (void)setObject:(id)newObject 
{ 
    [object release]; // send release message to current object 
    object = newObject; // set reference to newObject 
    [object retain]; // send retain message to newObject 
} 

이제는 ARC에서 코드에서 자신을 보유/해제 할 수 없지만 컴파일러에서 이러한 호출을 삽입합니다. 실제로는 위의 예에서 속성을 nil으로 설정하면됩니다. 예 :

[object release]; // send release message to current object 
object = nil; // set reference to nil 
[object retain]; // send retain message to nil (no effect) 

또한, 이것은 빙산의 일각에 불과하다 - 당신은 그들의 파괴에 의지하지 않고 누출 객체의 결과로 될 수있는 코드에서 no retain cycles를가 있는지 확인해야한다. 즉, weak 속성을 사용해야 할 때 strong 속성 (즉, 객체)에 대한 참조를 사용하고있는 곳이있을 수 있습니다.차이점은, 강한 참조가 retain 에드, 그리고 weak 참조 assign 에드 것으로, 전자는 retainCount가 증가하는 데되고 후자는 손으로 쓴 경우 다음과 같습니다 속성 할당 결과 : 그렇게하지

- (void)setObject:(id)newObject 
{ 
    object = newObject; 
} 
+2

당신은'dealloc' 메쏘드를 쓸 수 있습니다 - 당신은 아무 것도하지 않고'release'를 호출 할 수 없습니다. [슈퍼 dealloc]'. 그러나 정리를위한'dealloc' 메소드는 여전히 정결합니다. – Steve

+0

감사합니다. Alan, 나는 viewDidDisappear와 viewDidUnload 모두에서 모든 것을 0으로 설정하고 있습니다. dealloc은 호출되지만 실제 메모리 사용량에는 영향을 미치지 않습니다. 프로젝트의 평면 구조가 유지 사이클이 없어야하지만 한 번 더 확인해 보겠습니다. – nicktmro

+0

@ 스티브 저는 실제로 호출 될 때 내 자신의 dealloc을 작성했습니다. 그리고 예상했을 때 전화를받습니다. – nicktmro

관련 문제