ios影视项目解析 主要为讲block的细节 如果了解了 block的定义等 但是对运用不是很熟悉可以参考本文章
源于github上的影视项目解析
此项目在4app 和 github上都可以下载
项目截图:
此处为程序刚运行界面
程序应有一个discover控制器
找到discover控制器,然后可以根据项目的流程熟悉此项目的原理,从而学习到他们的架构思想
1 - (void)setupTableView 2 { 3 if (!_refreshControl) 4 { 5 _refreshControl = [[UIRefreshControl alloc] initWithFrame:CGRectMake(0, -44, 320, 44)]; 6 [self.refreshControl addTarget:self action:@selector(refreshFeed) forControlEvents:UIControlEventValueChanged]; 7 [self.tableView addSubview:_refreshControl]; 8 } 9 }
此处可看出是一个刷新空间的添加 采用懒加载的方式
- (void)refreshFeed { [self requestMovies]; }
他在viewdidload 还有刷新控件 改变的时刻调用requestMovies这个方法
找到这个方法
- (void)requestMovies { KMDiscoverListCompletionBlock completionBlock = ^(NSArray* data, NSString* errorString) { [self.refreshControl endRefreshing]; if (data != nil) [self processData:data]; else [self.networkLoadingViewController showErrorView]; }; KMDiscoverSource* source = [KMDiscoverSource discoverSource]; [source getDiscoverList:@"1" completion:completionBlock]; }
在这里 看了好久才明白 前面的 block 是对后面的调用来用的
也可以这样写 运行完全没错误
KMDiscoverSource* source = [KMDiscoverSource discoverSource]; [source getDiscoverList:@"1" completion:^(NSArray *data, NSString *errorString) { [self.refreshControl endRefreshing]; if (data != nil) [self processData:data]; else [self.networkLoadingViewController showErrorView]; } ];
这里面的意思
在这里他将 下载数据的方法 封装为一个block 这个是我主要要看的方法 总是对block不是很熟悉
点进去看一下
#import "KMBaseSource.h" typedef void (^KMDiscoverListCompletionBlock)(NSArray* data, NSString* errorString); @interface KMDiscoverSource : KMBaseSource + (KMDiscoverSource*)discoverSource; - (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock; @end
这个应该是一个工具类 用来返回discover 的数据
1 - (void)getDiscoverList:(NSString*)pageLimit completion:(KMDiscoverListCompletionBlock)completionBlock; 2 { 3 if (completionBlock) 4 { 5 NSDictionary* parameters = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:pageLimit, nil] forKeys:[NSArray arrayWithObjects:@"page", nil]]; 6 7 [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 8 9 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 10 [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 11 12 [manager GET:[self prepareUrl] parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) 13 { 14 NSLog(@"JSON: %@", responseObject); 15 NSDictionary* infosDictionary = [self dictionaryFromResponseData:operation.responseData jsonPatternFile:@"KMDiscoverSourceJsonPattern.json"]; 16 dispatch_async(dispatch_get_main_queue(), ^{ 17 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 18 completionBlock([self processResponseObject:infosDictionary], nil); 19 }); 20 } 21 failure:^(AFHTTPRequestOperation *operation, NSError *error) 22 { 23 NSLog(@"Error: %@", error); 24 dispatch_async(dispatch_get_main_queue(), ^{ 25 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 26 NSString* errorString = error.localizedDescription; 27 if ([errorString length] == 0) 28 errorString = nil; 29 completionBlock(nil, errorString); 30 }); 31 }]; 32 } 33 }
这里使用了第三方框架AFN
第一句是传入一个字典参数
第7行是 让状态栏的 网络传输图标 显示
第12行为 发送一个get请求
第15行是对json经行解析的封装 因为AFN是在异步执行 所以要得到主线程更新ui 把block的参数中的 data 给block 然后 在别的控制器调用这个block时候就会有参数 还可以进行自己的操作 可以在下面看到这个方法,还可以监听这个数据下载好没有
因为在err的参数里传的是nil 在运行的时候经行判断就好了
- (NSArray*)processResponseObject:(NSDictionary*)data { if (data == nil) return nil; NSArray* itemsList = [NSArray arrayWithArray:[data objectForKey:@"results"]]; NSMutableArray* sortedArray = [[NSMutableArray alloc] init]; for (NSDictionary* item in itemsList) { KMMovie* movie = [[KMMovie alloc] initWithDictionary:item]; [sortedArray addObject:movie]; } return sortedArray; }
可以清楚的看到这个函数 传出了一个字典
-------------------未完待续
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。