문제

배경:

탭 막대 응용 프로그램이 있습니다. 각 탭에는 네비게이션 컨트롤러가 포함되어있어 사용자가 한 뷰에서 다른 뷰에서 다른 뷰로 전환 할 수있는 내비게이션 컨트롤러가 포함되어 있습니다. didReceiveMemoryWarning 방법). 웹 서비스에서 데이터를 가져와 목록이 채워집니다.

문제:

iPhone 시뮬레이터의 "하드웨어> 메모리 경고 시뮬레이션"옵션을 사용하면 didReceiveMemoryWarning 내 뷰 컨트롤러에 대한 메소드는 사용자가보고있는 컨트롤러조차 요구됩니다. Active View Controller에서 사용하는 컨텐츠를 지우고 싶지 않습니다. 어떻게 달성 할 수 있습니까?

메모리 경고로 인해 데이터가 해제 된 후 데이터를 다시로드하기 위해 구현 해야하는 방법은 무엇입니까? (테이블 뷰 콜이 포함 된 View Controller 클래스가 viewDidLoad 메소드 사용자가 해당보기로 돌아 오는 경우, 뷰에 포함 된 경우 (uiwebview) viewDidLoad 메소드가 호출되지 않습니다. 왜 그런 겁니까?)

편집 (2009 년 1 월 30 일 금요일 -03:10 pm)

(참고 : 뷰 생성을 위해 인터페이스 빌더를 사용하고 있으며 loadView 메소드가 주석을 내립니다.)

따라서 View Controller가 메모리 경고 메시지를 받으면 수행되는 단계입니다.

  1. 다음 방법은 다음과 같습니다.

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning]; 
    }
    
  2. 전화의 결과로 [super didReceiveMemoryWarning], [self setView:nil] 자동으로 호출 되나요?

  3. 그렇다면 자원이 지워야한다면 setView 로컬 리소스를 지우려면 방법을 덮어 쓰야합니다.

  4. [self setView:nil] 뷰가 현재 활성화 된 경우 (기본적으로) 호출되지 않습니다. 오른쪽? - 나는 어떤 방법 이이 결정을 내리는 방법과 방법이 정말 궁금합니다.

확인해 주시겠습니까? 게다가이 접근법에 따라 오류가 발생했지만 추가 myObject = nil 출시 후 myObject 안에 dealloc 컨트롤러 클래스의 방법 문제를 수정했습니다. 감사.

도움이 되었습니까?

해결책

이것은 오래된 질문이지만 적절한 대답은 보이지 않으므로 여기에 간다.

메모리 경고가 수신되면 -didReceiveMemoryWarning "현재"이든 아니든 모든보기 컨트롤러에서 호출됩니다. 보기 컨트롤러는 단순히 메모리 경고 이벤트 브로드 캐스트를 듣고 있습니다.

메모리 경고시기에 View Controller의보기가 사용되지 않으면 컨트롤러는 속성을 NIL로 설정하여 언로드합니다. 보기가 사용되는지 어떻게 알 수 있습니까? 견해에 의해 -superview 재산. 만약에 view.superview NIL,보기는 나무의 일부가 아니며 안전하게 내릴 수 있습니다.

그런 일이 발생하면 컨트롤러가 발생합니다 -viewDidUnload 호출됩니다. 이곳은 모든 콘센트를 내릴 수있는 올바른 장소이며 다시 만들어 질 것입니다. -viewDidLoad.


그래서 무엇입니까 -didReceiveMemoryWarning 을 위한? 컨트롤러에는 액세스 할 때까지 실행되지 않는 객체가있을 수 있습니다. 예를 들어, 파일에서 큰 데이터 청크가 필요한 컨트롤러가있을 수 있지만 항상 그런 것은 아닙니다. 다음과 같은 속성 세트를 가질 수 있습니다.

- (NSData*)bigChunkOfData {
  // Get data from our instance variable _data, read from disk if necessary
  if (_data == nil) {
    _data = [[NSData alloc] initWithContentsOfFile:@"/path/to/data"];
  }
  return _data;
}

이렇게하면 처음으로 디스크의 데이터를 읽은 다음 인스턴스 변수로 유지합니다. 이후 _data 변수는 주문형으로 생성되며, 메모리가 낮은 상황에서 내리는 것이 안전합니다. 다음에 필요할 때 다시 만들어집니다.

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];

  [_data release];
  _data = nil;  // <-- Very important: don't leave strong references dangling.
}

다른 팁

나는 다음과 같이 청소를한다.

-(void)setView:(UIView*)view
{
    [super setView:view];
    if(view == nil)
    {
       // Our view has been cleared, therefore we should clean up everything 
       // we are not currently using
....

setView:nil 메모리 경고에 대한 응답으로 UIViewController가 호출합니다. 현재 뷰가 표시되지 않은 경우 기본적으로 알고 싶은 것입니다.

편집

후속 조치에 대한 답변으로 :

  1. 옳은.
  2. 그것이 내가하는 일이고 그것은 나를 위해 일합니다.
  3. 옳은. 의 구현 didReceiveMemoryWarning UiviewController에서 이것은 무엇을 하는가입니다. 당신이 무시하지 않는다면 didReceiveMemoryWarning, 그러면 UIViewController의 기본 클래스 구현이 호출됩니다. 재정의하면 분명히 호출해야합니다.

    [super didReceiveMemoryWarning]
    

내가 쓰는 모든 단일 뷰 콘트롤러에 대해 이것을 처리 할 필요가 없도록하려면 .. 방금 Xcode ViewController 템플릿을 만들었습니다.

더 많은 설명은 여기에 있습니다 http://iphone2020.wordpress.com/2010/05/30/efficient-memory handling-in-uiviewcontroller-part-1/

그것이 유용하다는 것을 알기를 바랍니다.

보기 관리 및 메모리 경고와 관련하여 :

UIKIT는 뷰 컨트롤러에서 내비게이션을 다시 허용 할뿐만 아니라 기존 컨트롤러의 다른 뷰 컨트롤러에 대한 탐색을 허용합니다. 이 경우 새로운 UIViewController가 할당 된 다음 시야에로드됩니다. 기존보기 컨트롤러는 화면을 벗어나 비활성화되지만 여전히 많은 객체를 소유하고 있습니다. 일부는 사용자 정의 속성 및 변수 및 뷰 속성/계층 구조의 다른 일부를 소유하고 있습니다. 또한 View Objects와 관련하여 새로운 가시보기 컨트롤러도 마찬가지입니다.

모바일 장치의 메모리가 제한되어 있기 때문에 두 개의 객체 세트 (하나는 오프 스크린 뷰 컨트롤러와 화면 뷰 컨트롤러에있는 두 세트를 소유하는 것이 너무 많을 수 있습니다. Uikit이 필요하다고 생각되면, 오프 스크린 뷰 컨트롤러의 메모리 중 일부를 되 찾을 수 있으며, 어쨌든 표시되지 않습니다. Uikit은 어떤 View 컨트롤러가 화면에 있고 어느 뷰 컨트롤러인지 알고 있습니다. presentModalViewController:animated: 또는 dismissModalViewControllerAnimated:). 따라서 압박감을 느낄 때마다 Uikit은 메모리 경고를 생성하여 View Hierarchy에서 오프 스크린 뷰를 내리고 방출 한 다음 사용자 정의 ViewDidUnload 메소드를 호출하여 속성 및 변수에 대해 동일한 작업을 수행 할 수 있습니다. Uikit은 Self.View를 자동으로 릴리스하여 ViewDidUnload 코드에서 변수 및 속성을 수동으로 릴리스 할 수 있습니다. 모든 오프 스크린 뷰 컨트롤러에 대해 그렇게합니다.

시스템이 메모리가 부족할 때 didReceiveMemoryWarning. 오프 스크린 뷰는 메모리 경고에 따라 재생 및 해제되지만 화면 뷰는 출시되지 않습니다. 보이고 필요합니다. 수업이 캐시, 이미지 등과 같은 많은 메모리를 소유 한 경우 didReceiveMemoryWarning 화면에 있더라도 제거 해야하는 곳입니다. 그렇지 않으면 앱이 빙하 시스템 리소스를 위해 종료 될 수 있습니다. 메모리를 정리하려면이 방법을 무시해야합니다. 당신이 전화를 기억하십시오 [super didReceiveMemoryWarning];.

더욱 정교한 설명이 있습니다. http://myok12.wordpress.com/2010/11/30/custom-uiviewcontrollers-their-views-and-their-mormory-management/

다행히도 시뮬레이터에는 편리한 기능이있어 메모리가 낮은 상황을 테스트에 넣을 수 있습니다. viewDidload와 didreceiveMemoryWarning에 nslog () 문을 넣으십시오.

- (void)viewDidLoad {
    NSLog(@"viewDidLoad"); 
    ...
}

- (void)didReceiveMemoryWarning {
    NSLog(@"didReceiveMemoryWarning");
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top