iOS 메모리 관리 면접 문제(반복 참조)

2564 단어
순환 참조
순환 인용의 실질: 여러 대상이 서로 강한 인용이 있어 시스템을 회수할 수 없습니다.
어떻게 순환 인용을 해결합니까?
1. 순환 인용을 피한다. 보통strong 인용을 weak 인용으로 바꾼다.예를 들어 속성을 수식할 때 weak로 Block에서 대상 방법을 호출할 때 약한 인용을 사용하면 두 개의 매크로를 사용할 수 있다
#define WS(weakSelf)            __weak __typeof(&*self)weakSelf = self; //  

#define ST(strongSelf)          __strong __typeof(&*self)strongSelf = weakSelf; // weakSelf

还可以使用__Block은 MRC 아래에서 변수를 수정합니다.Block은 참조 수를 증가시키지 않으며 ARC 아래에서 반복 참조를 방지합니다.Block 수식 대상은 강제로 인용되며 순환 인용을 피할 수 없습니다. 수동으로 해제해야 합니다.
2. 적절한 시기에 수동으로 순환 인용을 끊는다.보통 우리는 첫 번째 것을 사용한다.
1. 프록시(delegate) 순환 인용은 상호 순환 인용에 속한다.
delegate는 iOS에서 개발할 때 자주 만나는 순환 인용이다. 일반적으로delegate를 설명할 때 약한 인용 weak, 또는 assign을 사용해야 한다. 물론 assign을 사용할지 weak를 사용할지 선택해야 한다. MRC의 경우 assign만 사용할 수 있고 ARC의 경우 weak를 사용하는 것이 가장 좋다. 왜냐하면 weak 장식 변수가 풀린 후에 자동으로 nil을 가리키기 때문에 야생 지침이 존재하는 것을 방지하기 때문이다.
2. NSTimer 순환 참조는 상호 순환에 속한다.
컨트롤러 내에서 NSTimer를 속성으로 만들면 타이머가 만들어진 후에도 컨트롤러 대상을 강제로 인용하기 때문에 이 대상과 타이머는 서로 순환적으로 인용된다.어떻게 해결합니까?여기에서 우리는 수동으로 순환 인용을 끊을 수 있습니다. 만약 타이머를 반복하지 않는다면, 리셋 방법에서 타이머 invalidate를 nil로 병치하면 됩니다.만약 중복 타이머라면, 적당한 위치에서 invalidate를nil로 병치하면 됩니다
3. Block 순환 참조
간단한 예:
@property (copy, nonatomic) dispatch_block_t myBlock;
@property (copy, nonatomic) NSString *blockString;

- (void)testBlock {
    self.myBlock = ^() {
        NSLog(@"%@",self.blockString);
    };
}

Block은 Block의 대상을 소지하는 작업을 하기 때문에 그 중의 대상을 소지한 것과 같고 이때 Block의 대상이 이 Block을 소지하면 순환 인용을 초래할 수 있다.해결 방안은 을 사용하는 것이다weak 수식self
__weak typeof(self) weakSelf = self;

self.myBlock = ^() {
        NSLog(@"%@",weakSelf.blockString);
 };

4
  • 모든 Block이 순환 인용을 일으키는 것은 아니다.강제로 인용된 Block만 순환 인용이 발생합니다. 예를 들어dispatchsync(dispatch get main queue(),^{}), [UIView animate WithDuration: 1 animations:^{}] 이런 시스템 방법 등이나 Block은 그 속성이 아니라 임시 변수, 즉 창고 Block
  • [self testWithBlock:^{
        NSLog(@"%@",self);
    }];
    
    - (void)testWithBlock:(dispatch_block_t)block {
        block();
    }
    

    또 다른 장면은 Block 실행이 시작되었을 때 self 대상이 풀리지 않았고 실행 과정에서 self가 풀렸다. weak으로 장식했기 때문에 weakSelf도 풀렸다. 이때 Block에서 weakSelf를 방문했을 때 오류가 발생할 수 있다(nil 대상에게 이자를 보내면 붕괴되지 않지만 아무런 효과가 없다).이런 장면에 대해서는 Block에서 대상에 을 사용해야 한다strong 수식, Block 기간에 대상에 대한 소지, Block 실행이 끝난 후 소지를 해제합니다.
    __weak typeof(self) weakSelf = self;
    
    self.myBlock = ^() {
    
            __strong __typeof(self) strongSelf = weakSelf;
    
            [strongSelf test];
     };
    

    열문 추천


    2019 온사이트 iOS 면접문제 및 답안 요약!

    좋은 웹페이지 즐겨찾기