NSOperation 의 일반적인 사용 방법

5522 단어
멀티스레드 하면 NSThread, NSOperation, GCD 등 크게 세 가지 방법이 머릿속에 떠오른다.그런데...아직도 GCD를 사용하고 있습니까?GCD 기반 캡슐화된 NSOperation 을 살펴봅시다.거위..NSOperation 은 추상적인 기본 클래스입니다.아버지는 부리기 어려워 두 아들인 NS Invocation Operation과 NS Block Operation을 부릴 수밖에 없었다.자자자, 데모로 가자.
NSInvocationOperation
-(void)InvocationOperation
{
    NSInvocationOperation *invo = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testInvocation) object:nil];
    //    start !
    [invo start];
}

-(void)testInvocation
{
    NSLog(@"%@",[NSThread currentThread]);
}

실행 결과: 기본 라인의
19:05:38.346 [2689:142129] {number = 1, name = main}

NSBlockOperation
효과가 좋아지기 위해서 Block을 몇 개 더 해봐요.
-(void)BlockOperation
{
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1---%@",[NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"2---%@",[NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"3---%@",[NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"4---%@",[NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"5---%@",[NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"6---%@",[NSThread currentThread]);
    }];
    //   start  ?!
    [blockOperation start];
}

실행 결과
19:00:35.899 [2656:140762] 4---{number = 5, name = (null)}
19:00:35.899 [2656:140730] 1---{number = 1, name = main}
19:00:35.899 [2656:140763] 3---{number = 4, name = (null)}
19:00:35.899 [2656:140765] 2---{number = 3, name = (null)}
19:00:35.899 [2656:140762] 5---{number = 5, name = (null)}
19:00:35.899 [2656:140730] 6---{number = 1, name = main}

요약: 1.NSBlockOperation은 멀티스레드를 구현했습니다.하지만!모든 Block을 하위 라인에 넣는 것은 아닙니다. 주 라인과 하위 라인이 모두 있습니다.어떻게 된 거야?맵냐, 다시 관찰 라인 id호: [2656:140762]와 [2656:140730]는 두 번 출현했다.이것은 우선 Block을 주 라인에 놓고 실행합니다. 주 라인에 실행 중인 코드가 있으면 새로운 라인을 열 것입니다.2. 같은 BlockOperation의 코드는 동기화됩니다.이것은 인쇄의 운행 시간에 19:00:35.899를 알 수 있다.
NSInvocation Operation과 NSBlockOperation은 대단한데...그러자 NSOperationQueue는 불복했다.
NSOperationQueue
-(void)OpertationQueue
{
    //invocation   queue   
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *invo = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testInvocation) object:nil];
    [queue addOperation:invo];
    
    //block   queue   
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"blockOperation---%@",[NSThread currentThread]);
    }];
    [queue addOperation:blockOperation];
    
    //      ,    
    [queue addOperationWithBlock:^{
        NSLog(@"addOperationWithBlock---%@",[NSThread currentThread]);
    }];
}

실행 결과: 세 개의 라인이 비동기적으로 실행되는 것을 볼 수 있습니다.NSOperationQueue에 직접dd를 보내면 됩니다. 수동으로 startNSOperationQueue를 사용하지 않아도 적당한 시기에 자동으로 호출됩니다.2.add가 NSOperationQueue에 도착하면 자동으로 하위 스레드로 이동합니다.
20:20:25.095 [2971:164505] {number = 3, name = (null)}
20:20:25.095 [2971:164519] blockOperation---{number = 4, name = (null)}
20:20:25.095 [2971:164504] addOperationWithBlock---{number = 5, name = (null)}

......칠판 봐!이 NSOperation 에는 의존, 스레드의 실행 순서, 한마디의 일도 추가할 수 있다
addDependency
-(void)addDependency{
    NSInvocationOperation *invo1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test1) object:nil];
    NSInvocationOperation *invo2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test2) object:nil];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [invo1 addDependency:invo2];
    [queue addOperation:invo1];
    [queue addOperation:invo2];
}

-(void)test1
{
    NSLog(@"invo1---%@",[NSThread currentThread]);
}

-(void)test2
{
    NSLog(@"invo2---%@",[NSThread currentThread]);
}

실행 결과: invo1을 invo2에 의존하도록 설정했습니다. 몇 번 실행하면 이 순서입니다.
20:40:14.201 [3207:175388] invo2---{number = 3, name = (null)}
20:40:14.202 [3207:175389] invo1---{number = 4, name = (null)}

⚠️warning 1.순환적으로 의존하지 마라. 그렇지 않으면 순환적으로 인용될 것이다.2. invocaiton과 Block을 섞으려면 간식을 많이 먹는다.3. 국경이 없고 서로 다른 대기열의 NSOperation 대상이 설정한 의존 관계에 의존한다.
우선 순위와 의존 관계의 차이
Foundation---NSOperation을 보세요.h당신은 우선 순위를 직접 설정할 수 있음을 발견할 수 있습니다.Bu t!우선순위와 의존 관계는 다르다. 우선순위는 의존 관계를 대체할 수 없다. 우선순위는 준비된operations에 대해 실행 순서를 정할 뿐이다.우선 의존 관계를 만족시킨 다음에 우선순위에 따라 모든 준비된 작업 중에서 우선순위가 가장 높은 실행을 선택하십시오.
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
    NSOperationQueuePriorityVeryLow = -8L,
    NSOperationQueuePriorityLow = -4L,
    NSOperationQueuePriorityNormal = 0,
    NSOperationQueuePriorityHigh = 4,
    NSOperationQueuePriorityVeryHigh = 8
};

기타 사용 가능한 속성setMaxConcurrentOperationCount; // [queue setSuspended:YES]; // [queue setSuspended:NO]; // [operation waitUntilFinished]; // , operation .그래서...유목유발견은 GCD에 기초하여 봉인된 것이다

좋은 웹페이지 즐겨찾기