dispatch _once可以保证线程安全,static修饰全局变量:
在这里我将这个方法写成类方法,方便以后调用
+ (instancetype)sharedManger {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (manger == nil) {
manger = [[BeanFlapMainViewManger alloc] init];
}
});
return manger;
}
我使用块(block)进行传值
//成功返回对应的model
typedef void (^BFMainViewNowBlock)(BeanFlapMainViewModel *mainViewNowModel);
//失败返回error
typedef void (^ErrorBlock)(NSError * _Nonnull error);
NS_ASSUME_NONNULL_BEGIN
@interface BeanFlapMainViewManger : NSObject
+ (instancetype)sharedManger;
//获取影院热映数据
- (void)fetchMainViewFilmSucceed:(BFMainViewNowBlock) succeedBlock error:(ErrorBlock) errorBlock;
@end
NS_ASSUME_NONNULL_END
函数:
我以最近在写的豆瓣的请求为例
- (void)fetchMainViewFilmSucceed:(BFMainViewNowBlock)succeedBlock error:(ErrorBlock)errorBlock {
//普普通通的网络请求
NSString *filmNowURLStr = [NSString stringWithFormat:@"http://douban.uieee.com/v2/movie/in_theaters"];
NSURL *filmNowURL = [NSURL URLWithString:filmNowURLStr];
NSURLRequest *filmNowURLRequest = [NSURLRequest requestWithURL:filmNowURL];
NSURLSession *filmNowURLSeesion = [NSURLSession sharedSession];
NSURLSessionDataTask *filmNowDataTask = [filmNowURLSeesion dataTaskWithRequest:filmNowURLRequest completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error) {
if (error == nil) {
NSDictionary *getDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
BeanFlapMainViewModel *filmNowModel = [[BeanFlapMainViewModel alloc] initWithDictionary:getDictionary error:&error];
//成功返回请求到的数据
succeedBlock(filmNowModel);
} else {
errorBlock(error);
}
}];
[filmNowDataTask resume];
}
在你需要用它的时候先创建后调用方法就行
[[BeanFlapMainViewManger sharedManger] fetchMainViewFilmSucceed:^(BeanFlapMainViewModel *resultModel){
self.myView.headView.myModel = [[BeanFlapMainViewModel alloc] init];
self.myView.headView.myModel = resultModel;
BFSubjectsModel *subjectModel = [[BFSubjectsModel alloc] init];
subjectModel = self -> _myModel.subjects[0];
} error: ^(NSError *error) {
NSLog(@"--- error");
}];
[_myView.tableView reloadData];
一般我们在使用时,将获取到的字典数据赋给model(该model继承于JSONModel),只需要Model的属性和数据解析出的名字一样,JSONModel会自动解析进行赋值,这就是JSONModel的强大之处
在嵌套数据时, 我们应该对每一个要嵌套的都写成一个类,但并不是意味着要写成多个类文件,而是只需要在一个类文件里把该有的写好就行
例如这是我请求到的字典数据:
{
"count":20,
"start":0,
"total":61,
"subjects":[
{
"rating":{
"max":10,
"average":8.6,
"details":{
"1":214,
"2":185,
"3":1298,
"4":5897,
"5":6350
},
"stars":"45",
"min":0
},
"genres":[
"剧情",
"爱情"
],
"title":"少年的你",
"casts":[
{
"avatars":{
"small":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p36798.webp",
"large":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p36798.webp",
"medium":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p36798.webp"
},
"name_en":"Dongyu Zhou",
"name":"周冬雨",
"alt":"https://movie.douban.com/celebrity/1274224/",
"id":"1274224"
},
{
"avatars":{
"small":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507879990.66.webp",
"large":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507879990.66.webp",
"medium":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1507879990.66.webp"
},
"name_en":"Jackson Yee",
"name":"易烊千玺",
"alt":"https://movie.douban.com/celebrity/1340022/",
"id":"1340022"
},
{
"avatars":{
"small":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1561012942.87.webp",
"large":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1561012942.87.webp",
"medium":"http://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1561012942.87.webp"
},
"name_en":"Fang Yin",
"name":"尹昉",
"alt":"https://movie.douban.com/celebrity/1340310/",
"id":"1340310"
}
],
"durations":[
"135分钟"
],
"collect_count":161569,
"mainland_pubdate":"2019-10-25",
"has_video":false,
"original_title":"少年的你",
"subtype":"movie",
"directors":Array[1],
"pubdates":Array[1],
"year":"2019",
"images":Object{...},
"alt":"https://movie.douban.com/subject/30166972/",
"id":"30166972"
},
{
"rating":{
"max":10,
"average":7.1,
"details":{
"1":146,
"2":1376,
"3":10117,
"4":10166,
"5":2509
},
"stars":"35",
"min":0
},
"genres":[
"剧情",
"动作",
"科幻"
],
"title":"双子杀手",
"casts":[
{
"avatars":{
"small":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p41483.webp",
"large":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p41483.webp",
"medium":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p41483.webp"
},
"name_en":"Will Smith",
"name":"威尔·史密斯",
"alt":"https://movie.douban.com/celebrity/1027138/",
"id":"1027138"
},
{
"avatars":{
"small":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p32684.webp",
"large":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p32684.webp",
"medium":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p32684.webp"
},
"name_en":"Mary Elizabeth Winstead",
"name":"玛丽·伊丽莎白·温斯特德",
"alt":"https://movie.douban.com/celebrity/1041018/",
"id":"1041018"
},
{
"avatars":{
"small":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p5321.webp",
"large":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p5321.webp",
"medium":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p5321.webp"
},
"name_en":"Clive Owen",
"name":"克里夫·欧文",
"alt":"https://movie.douban.com/celebrity/1025147/",
"id":"1025147"
}
],
"durations":[
"117分钟"
],
"collect_count":125796,
"mainland_pubdate":"2019-10-18",
"has_video":false,
"original_title":"Gemini Man",
"subtype":"movie",
"directors":[
{
"avatars":{
"small":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p595.webp",
"large":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p595.webp",
"medium":"http://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p595.webp"
},
"name_en":"Ang Lee",
"name":"李安",
"alt":"https://movie.douban.com/celebrity/1054421/",
"id":"1054421"
}
],
"pubdates":[
"2019-10-11(美国)",
"2019-10-18(中国大陆)"
],
"year":"2019",
"images":{
"small":"http://img1.doubanio.com/view/photo/s_ratio_poster/public/p2570906505.webp",
"large":"http://img1.doubanio.com/view/photo/s_ratio_poster/public/p2570906505.webp",
"medium":"http://img1.doubanio.com/view/photo/s_ratio_poster/public/p2570906505.webp"
},
"alt":"https://movie.douban.com/subject/3097572/",
"id":"3097572"
}
],
"title":"正在上映的电影-北京"
}
我现在想获取它的电影名及图片和评分,但是很明显,它们没在同一层,那么需要多个model嵌套使用,即:
#import "JSONModel.h"
@protocol BFSubjectsModel
@end
NS_ASSUME_NONNULL_BEGIN
@interface BFRatingModel : JSONModel
@property (nonatomic) double average;
@end
@interface BFImagesModel : JSONModel
@property (nonatomic, strong) NSString *medium;
@end
@interface BFSubjectsModel : JSONModel
@property (nonatomic, strong) BFRatingModel *rating;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) BFImagesModel *images;
@end
@interface BeanFlapMainViewModel : JSONModel
@property (nonatomic, strong) NSString *total;
@property (nonatomic, copy) NSArray<BFSubjectsModel> *subjects;
@end
NS_ASSUME_NONNULL_END
model的.m文件只需要写一个函数,该函数用于 就算API中没有请求到类中的,映射有问题也不会报错(直接忽略)
#import "BeanFlapMainViewModel.h"
@implementation BeanFlapMainViewModel
+(BOOL)propertyIsOptional:(NSString *)propertyName{
return YES;
}
@end
@implementation BFSubjectsModel
+(BOOL)propertyIsOptional:(NSString *)propertyName{
return YES;
}
@end
@implementation BFRatingModel
+(BOOL)propertyIsOptional:(NSString *)propertyName{
return YES;
}
@end
@implementation BFImagesModel
+(BOOL)propertyIsOptional:(NSString *)propertyName{
return YES;
}
@end