AFNetworking 소스 읽기
,
//
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//
manager.requestSerializer.timeoutInterval = 10;
// ( Json)
manager.responseSerializer = [AFJSONResponseSerializer serializer];
// GET
[manager GET:urlString
parameters:nil
success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
NSLog(@" ");
}
failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
NSLog(@" ");
}];
2. 대체적인 프레임워크 이 소스 오픈 프레임워크는 NSURLconnection과 NSURLSession을 바탕으로 개발된 것이다.그중에는 두 가지 관리 클래스가 있는데 그것이 바로 AFHTTPRequest Operation Manager와 AFHTTPSession Manager이다.또 다른 주요 클래스는 AFURLconnection Operation이다. 이것은 사용자 정의 NSOperation으로 네트워크 요청 작업, 리셋, 메인 라인으로 전송하는 데 사용된다.3. AFURLconnection Operation은 먼저 라인을 논의한다.우리가 네트워크 요청을 하는 것은 다음과 같은 몇 가지가 있다. 1) 메인 스레드 동기화 요청: 이것은 메인 스레드를 막아서 일반적으로 아무도 사용하지 않는다.2) 메인 스레드 호출 비동기 요청: NSURLconnection은 메인 스레드 Runloop에서 리셋 이벤트를 터치합니다. 메인 스레드의 모드(㎡는 상태로 이해할 수 있죠)는 두 가지 기본값이 있습니다. NSDefaultRunLoopMode입니다. 평소의 상태와 UITrackingRunLoopMode를 기록하고 ScrollView가 미끄러질 때의 상태를 추적합니다.NSURLconnection의 리셋을 언제든지 받아들이려면 NSRunLoopCommonModes 상태로 설정해야 합니다. 계속 미끄러지는 상태에서는 리셋을 처리할 수 없기 때문입니다.그러나 이렇게 하면 애니메이션 효과에도 영향을 줄 수 있다.3) 서브스레드 호출 동기화 요청: 이때 요청을 진행하면 주 스레드의 상태에 영향을 주지 않지만 하나의 네트워크 요청을 처리하려면 하나의 스레드를 차지해야 한다. 이 스레드는 리셋을 진행할 때까지 막힌다. 요청이 비교적 많으면 여러 스레드를 차지하고 자원 낭비를 초래한다.4) 서브루틴 호출 비동기 요청: 이런 상황에서 상주 서브루틴을 설정하여 네트워크 요청의 리셋을 할 수 있다. 이렇게 여러 개의 네트워크 요청이 요청될 때 리셋은 모두 통일된 서브루틴에 있고 이후에 메인 루틴으로 전달될 때 메인 루틴에 영향을 주지 않는다.위 방식3)에 비해 적지 않은 우세가 있다.이 틀은 방식 4)을 채택한다.소스:
+ (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;
}
operation이queue에 입력되면 operation 방법이 자동으로 호출됩니다.
- (void)start;
이 프레임워크의 이 방법은 위에서 만든 라인에connection 요청 네트워크 데이터를 만들고 이 라인에서 리셋합니다.또한 받은 데이터를 메모리에 쓰기 위해 outputStream을 만들었습니다.
- (NSOutputStream *)outputStream {
if (!_outputStream) {
self.outputStream = [NSOutputStream outputStreamToMemory];
}
return _outputStream;
}
보충:operation에는 하나의 상태기가 포함되어 있으며 현재operation의 상태를 설명하고 KVO로 관리합니다.상태는
isReady → isExecuting → isFinished
사용자 정의operation은 상태기를 추가해야 합니다.queue에 가입하면 실행할 수 없습니다.queue의 의존과 같이 A는 B에 의존한다. B의 상태기 상태가 isFinished일 때만 A를 실행할 수 있다.이 프레임의 원본 코드는 다음과 같습니다.
typedef NS_ENUM(NSInteger, AFOperationState) {
AFOperationPausedState = -1,
AFOperationReadyState = 1,
AFOperationExecutingState = 2,
AFOperationFinishedState = 3,
};
- (void)setState:(AFOperationState)state {
if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) {
return;
}
[self.lock lock];
NSString *oldStateKey = AFKeyPathFromOperationState(self.state);
NSString *newStateKey = AFKeyPathFromOperationState(state);
[self willChangeValueForKey:newStateKey];
[self willChangeValueForKey:oldStateKey];
_state = state;
[self didChangeValueForKey:oldStateKey];
[self didChangeValueForKey:newStateKey];
[self.lock unlock];
}
서버에서 데이터를 받으면 connection의 프록시 방법이 호출됩니다.
- (void)connection:(NSURLConnection __unused *)connection
didReceiveData:(NSData *)data;
받은 데이터를 메모리에 쓰고 받은 후에 호출합니다
- (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection;
메모리에 있는 데이터를 꺼내서connection을 닫습니다. 이operation상태기는 isFinished에 있고 이operation의completionBlock를 호출하여 받은 데이터를 조작합니다.
이 프레임워크는 Block 작업에 대해 다음과 같은 유형을 자주 볼 수 있습니다.
__weak __typeof(self)weakSelf = self;
[super setCompletionBlock:^ {
__strong __typeof(weakSelf)strongSelf = weakSelf;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_group_t group = strongSelf.completionGroup ?: url_request_operation_completion_group();
dispatch_queue_t queue = strongSelf.completionQueue ?: dispatch_get_main_queue();
#pragma clang diagnostic pop
dispatch_group_async(group, queue, ^{
block();
});
dispatch_group_notify(group, url_request_operation_completion_queue(), ^{
[strongSelf setCompletionBlock:nil];
});
}];
}
Block과self 사이의 순환 인용을 방지하기 위해 weakself를 만듭니다.그러나 그 다음에 strongself를 만들어서 self가 가리키는 대상을 미리 방출하는 것을 방지합니다. (Block의 실행은 비동기적입니다. Block이 실행되지 않았을 수도 있습니다. Operation은 dealloc이고 Block에서 다시 사용되었습니다. 저자는 순환 인용을 무시했습니다. 마지막으로 이 Block을 nil로 설정했기 때문에 순환 인용이 되지 않습니다.)또strongSelf 이후에 자동으로 방출되어 순환 인용을 일으키지 않기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.