runloop 사용

5597 단어 #iOS 기본
하나.이론Runloop: 글자의 뜻: 러닝, 실제적으로 그는 하나의 대상이다. 이 대상은 처리해야 할 사건과 정보를 관리하고 입구 함수를 제공하여do{}while{}논리를 집행한다. 라인이 이 함수를 집행한 후에 메시지를 받아들이기->대기->처리하는 순환에서 이 순환이 끝날 때까지 함수가 되돌아온다.RunLoop은 루틴의 순환이다. RunLoop은 순환 중에 끊임없이 검출되고 Input sources(입력 소스)와 Timer sources(정시 소스) 두 가지 소스를 통해 이벤트를 받아들이기를 기다린다.그리고 받은 이벤트 알림 라인을 처리하고 이벤트가 없을 때 휴식을 취합니다.OSX/iOS 시스템에서 두 가지 대상을 제공했는데 그것이 바로 NSRunLoop(후자의 비선정 안전에 계승된)과 CFRunLoopRef(CoreFoundation 프레임워크에 있기 때문에 선정 안전이다)이다.ios에서 스레드를 켜면 성능을 소모합니다. 메인 스레드는 1m를 소모하고 백엔드 스레드는 512k의 메모리를 소모합니다. CFRunLoopRef의 코드는 원본입니다. 여기서http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz둘.api CFRunLoopRef runloop 본류 CFRunLoopMode Ref runloop 실행 모드는 5가지 모드가 있습니다.kCFRunLoopDefaultMode: 기본 모드입니다. 보통 이 모드에서 실행됩니다.UITracking RunLoopMode: 추적 모드, Scrollview 미끄럼이 다른 영향을 받지 않도록 보증합니다.UIInitializationRunLoopMode: 프로그램을 시작한 후의 과도 모드, 시작이 완료된 후에는 4.GSEventReceivRunLoopMode: 보통 5가 안 돼요.kCFRunLoopCommonModes: 자리 차지 모드, 1 및 2 로고로 사용
CFRunLoopSourceRef runloop의 내용 - 이벤트 소스, 입력 소스는 Source0 Source1 두 가지
CFRunLoopTimerRef.runloop 내용 - 타이머 CFRunLoopObserverRef 관찰자
하나의 RunLoop은 몇 개의 모드를 포함하고, 각각의 모드는 몇 개의 Source/Timer/Observer를 포함한다.RunLoop의 주 함수를 호출할 때마다 그 중 하나만 지정할 수 있습니다. 이 모드는CurrentMode라고 부릅니다.Mode 를 전환하려면 Loop 을 종료하고 Mode 를 다시 지정해야 합니다.이렇게 하는 것은 주로 서로 다른 그룹의 Source/Timer/Observer를 분리하여 서로 영향을 주지 않도록 하기 위해서이다.
셋.NSTimer를 사용하면 타이머가 지연됩니다. 일반 프로젝트의 첫 페이지 헤더에는 (scrollerview+timer)+tableview의 조합이 있습니다. tableview를 미끄러질 때 스크롤 그림이 나타납니다. 스크롤을 멈추는 것은 타임을 메인 라인의mainrunloop에 추가했기 때문입니다. 메인 라인의 NSDefaultRunLoopMode는 메인 라인의runloop이 다른 이벤트가 없을 때 타임러가 정상적으로 실행됩니다.main runloop이 다른 itme(scoure/기타 이벤트)를 받아들이면 UITracking RunLoop Mode로 전환됩니다. 슬라이딩이 멈추면 기본적으로 이 문제를 해결하는 두 가지 방법이 있습니다.timer: 두 가지 방식으로 초기화하고//스레드 NSThread*subThead = [[NSThread alloc] initWithTarget:self selector:@selector(timerTest)object:nil];self.subThread = subThead; //스레드 시작 [subThead start]; -(void)timerTest{ @autoreleasepool {
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerUpdate) userInfo:nil repeats:YES];
 [[NSRunLoop currentRunLoop] run];
}

새로고침 ui - (void) timerUpdate {//NSLog(@ 현재 스레드:%@", [NSThread currentThread]]]);/NSThread NSThread curread currentThrererereread Threread Thread [NSThread currentThrereread Thread]]);//NSThread NSThread NSThread tiread tiread tiread tiread tireat tireat tireat Timer Threat Threat Threat Timer Timer Uprat Threa a a, ^{self.count –; NSString *timerText =[NSString stringWithFormat:@"타이머:%ld",self.count];self.TimeLable.text = timerText; }); } timer는 두 가지 방식으로 첫 번째를 만들 수 있습니다: scheduledTimerWithTimeInterval 두 번째:imerWithTimeInterva 우리는 두 번째 방식으로 timer를 초기화한 다음에 현재 라인에 가입하여 NSRunLoopCommonModes 모드를 사용합니다. self.timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(addTime) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
tableview 슬라이딩 카드 슬라이딩 이후 불러오기(image 디스플레이 지연) 핵심 코드//주요 코드 [imageView perform Selector OnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];백엔드 상주 스레드(self.subTherad = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil]; [self.subTherad start];
  • (void)run{//런루프에 timer,source 또는observer만 추가하면 계속 실행됩니다. 런루프는 이벤트를 감청하기 위해 입력 소스나 타이머를 포함해야 합니다. 하나도 없으면 런루프가 시작된 후 종료됩니다.
    //1、 input source
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
    //2、 
    //    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    //    [[NSRunLoop currentRunLoop] run];
    
  • } [self perform Selector:@selector(test) onThread:self.subTherad withObject:nil waitUntilDone:NO]를 호출합니다.
    무너진 프로그램을 기사회생시키는 참고:https://www.jianshu.com/p/fee0c5155b8e넷.라인과의 관계는 라인과 RunLoop 사이에 일일이 대응하고 그 관계는 전역적인 Dictionary에 저장된다(key는thread,value는runloop,안드로이드 위에도looper가 있다).루프가 처음 만들어졌을 때 RunLoop이 없었습니다. 만약 당신이 주동적으로 가져오지 않았다면, 루프는 없었을 것입니다.RunLoop의 생성은 처음 가져왔을 때 발생했고, RunLoop의 삭제는 라인이 끝났을 때 발생했습니다.한 라인의 내부에서만 RunLoop을 얻을 수 있습니다. (주 라인을 제외합니다.)
    넷.주의사항은 RunLoop이 작동하려면 Item(source,observer 또는timer)이 있어야 합니다. 메인 라인이 계속 존재하고 언제든지 깨어날 수 있는 이유는 시스템에 많은 Item을 추가해야 합니다. 퍼포먼스 selector가 백엔드 라인에서 실행될 때 이 라인은 열려 있는runLoop이 있어야 합니다. 스크롤이 미끄러질 때 같은 페이지의 타이머가 왜 멈추나요?
    timer를 만들 때 시스템은 기본적으로 timer를 kCFRunLoopDefaultMode 모드에 추가하지만 페이지가 굴러갈 때 RunLoop의 모드는 자동으로 UITrackingRunLoopMode 모드로 전환되기 때문에 timer는 효력을 상실하고 미끄럼을 멈추면 RunLoop은 NSDefaultRunLoopMode 모드로 전환되기 때문에 timer는 다시 시작합니다.
    어떻게 테이블뷰가 미끄러질 때 그림을 불러오는 것을 지연시켜 유창도를 높입니까?NSDefaultRunLoopMode 모드에 그림을 불러오는 것을 피하면 [self.imageView performselector:@selector(setImage:) withObject: [UIImage image Named:@"abc]afterDelay:2.0 inModes:@[NSDefaultRunLoopMode]]를 피할 수 있습니다.흔히 말하는 AFNetworking 상주 루틴 보존은 어떤 원리입니까?
  • (void)networkRequestThreadEntryPoint:(id)__unused object { @autoreleasepool { [NSThread currentThread] setName:@”AFNetworking”]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run]; } }
  • (NSThread *)networkRequestThread { static NSThread *_networkRequestThread = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil]; [_networkRequestThread start]; }); return _networkRequestThread; }
  • 좋은 웹페이지 즐겨찾기