AFNetworking 3.x 읽기 노트 (1)

7170 단어
한 두 달 전에 AFN의 2를 읽었어요.프로젝트에서 계속 사용했기 때문에 x의 원본 코드입니다.x, 요 며칠 짬을 내다.x의 코드를 보충합니다.첫 번째 노트에서 AFN을 기록한 데모는 데모가 있으면 이 라이브러리를 어떻게 사용하는지 알고 업무 지식을 습득할 수 있다. 그리고 밑바닥의 원본 코드를 깊이 있게 공부하면 서로 다른 각도에서 문제를 볼 수 있다.

Delegate의 내용


우선 AppDelegate에는 다음과 같은 코드가 있는데 그 중에서 NSURLCacheAFNetworkActivityIndicatorManager 두 종류는 배워야 한다.
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
    
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]; 

NSURLCache


NSURLcache에서 언급한 NSURLcache는 응용 프로그램의 URL 요청에 메모리와 디스크의 종합 캐시 메커니즘을 제공합니다.기본 라이브러리 URL 마운트 시스템의 일부로서 NSURLconnection/NSURLSession을 통해 마운트된 요청은 NSURLcache에서 처리됩니다.서버에서 다운로드를 요청하면 캐시 응답이 로컬에 저장됩니다.다음에 같은 요청을 다시 시작하면 로컬에 저장된 응답이 바로 되돌아와 서버에 연결할 필요가 없습니다.NSURLcache는 자동적이고 투명하게 응답을 되돌려줍니다. 구체적인 캐시 정책은 클라이언트와 서버가 공동으로 협상하여 해결합니다.
요청한 NSURLRequest에는 클라이언트가 요청할 때 설정한 캐시 정책cachePolicy 속성이 있습니다.구체적인 몇 가지 모델은 공식 문서를 참고할 수 있으며 다음 표는 실제에서 자주 사용하는 몇 가지 전략과 그 실제 의미를 나타낸다.
매거
속뜻
UseProtocolCachePolicy
기본 동작
ReloadIgnoringLocalCacheData
캐시를 사용하지 않음
ReturnCacheDataElseLoad
캐시 사용(기한이 지났든 안 지났든) 캐시에 없으면 네트워크에서 불러오기
ReturnCacheDataDontLoad
오프라인 모드: 캐시를 사용하지만 네트워크에서 불러오지 않습니다.

AFNetworkActivityIndicator Manager에서 유지 보수하는 상태기


이 클래스는AFN의 중감청 네트워크 상태의 클래스입니다.주로 현재 요청 관리status baractivity indicator에 따라 표시되고 닫힙니다.AFNetworkActivityIndicatorManager는 현재 네트워크 프레임워크에 요청이 있는지 기록하고 activityCount 속성을 통해 현재 동시session 요청의 개수를 유지하여 status bar에 국화를 표시할지 여부를 결정합니다.
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
    AFNetworkActivityManagerStateNotActive,
    AFNetworkActivityManagerStateDelayingStart,
    AFNetworkActivityManagerStateActive,
    AFNetworkActivityManagerStateDelayingEnd
};

데모에서 좋은 예시를 제시했는데 app가 시작된 후에 직접 호출[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]하여 국화의 제어를 감청하는데 기본적으로 감청하지 않았다.
상태기의 핵심 방법은 다음과 같습니다.
#pragma mark - Internal State Management
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
    @synchronized(self) {//        
        if (_currentState != currentState) {
            [self willChangeValueForKey:@"currentState"];
            _currentState = currentState;
            switch (currentState) {
                //     ,           
                case AFNetworkActivityManagerStateNotActive:
                    [self cancelActivationDelayTimer];
                    [self cancelCompletionDelayTimer];
                    [self setNetworkActivityIndicatorVisible:NO];
                    break;
                //   delay    ->           
                case AFNetworkActivityManagerStateDelayingStart:
                    [self startActivationDelayTimer];
                    break;
                //     active  ,    
                case AFNetworkActivityManagerStateActive:
                    [self cancelCompletionDelayTimer];
                    [self setNetworkActivityIndicatorVisible:YES];
                    break;
                //   delay    ->delay time         NotActive
                case AFNetworkActivityManagerStateDelayingEnd:
                    [self startCompletionDelayTimer];
                    break;
            }
            [self didChangeValueForKey:@"currentState"];
        }
    }
}

- (void)updateCurrentStateForNetworkActivityChange {
    if (self.enabled) {
        switch (self.currentState) {
            case AFNetworkActivityManagerStateNotActive:
                if (self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateDelayingStart];
                }
                break;
            case AFNetworkActivityManagerStateDelayingStart:
                //No op. Let the delay timer finish out.
                break;
            case AFNetworkActivityManagerStateActive:
                if (!self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateDelayingEnd];
                }
                break;
            case AFNetworkActivityManagerStateDelayingEnd:
                if (self.isNetworkActivityOccurring) {
                    [self setCurrentState:AFNetworkActivityManagerStateActive];
                }
                break;
        }
    }
}

감청방송이 AFNetworkingTaskDidResumeNotification,AFNetworkingTaskDidSuspendNotification,AFNetworkingTaskDidResumeNotification 등Notification을 받았을 때incrementActivityCount,decrementActivityCount방법으로 _activityCount방법을 바꾸고 updateCurrentStateForNetworkActivityChange방법으로 상태를 바꾼다.

다른 배울 점


timer에서 commomMode 사용


timer를 NSRunLoopCommonModes에 추가하면 언제든지 timer의 운행을 보장할 수 있습니다
[[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes];

.hreadonly를 사용하여,.m 수정 가능


이 클래스에는 속성networkActivityIndicatorVisible이 있고 외부 접근이 필요하다면readonly 내부는 수정할 수 있습니다.다음 방법을 참조하십시오.
// .h 
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

//.m 
@property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

AFNetworking의 몇 가지 알림


아마도 다른 곳에서도 이 몇 가지 통지가 필요할 것이다
AFNetworkingTaskDidResumeNotification
AFNetworkingTaskDidSuspendNotification
AFNetworkingTaskDidCompleteNotification

데모에서 [self.refreshControl setRefreshingWithStateOfTask:task]라는 방법을 사용했다.원본 코드를 통해 이 몇 개의 알림을 사용하여refresh의 시작과 갱신을 제어하는 것을 알 수 있습니다.
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

    [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
    [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];

    if (task) {
        UIRefreshControl *refreshControl = self.refreshControl;
        if (task.state == NSURLSessionTaskStateRunning) {
            [refreshControl beginRefreshing];

            [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
            [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
        } else {
            [refreshControl endRefreshing];
        }
    }
}

좋은 웹페이지 즐겨찾기