RQExerciseModule.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. //
  2. // RQExerciseModule.m
  3. // JSJP
  4. //
  5. // Created by 张嵘 on 2021/8/12.
  6. //
  7. #import "RQExerciseModule.h"
  8. /// 刷新TableView
  9. NSString * const RQRefreshExerciseTableViewNotification = @"RQRefreshExerciseTableViewNotification";
  10. /// 答题结果
  11. NSString * const RQAnswerResultsNotification = @"RQAnswerResultsNotification";
  12. /// 答题结果 key
  13. NSString * const RQAnswerResultsKey = @"RQAnswerResultsKey";
  14. /// 练习模式Key
  15. NSString * const RQExerciseTypeKey = @"RQExerciseTypeKey";
  16. /// 考试页面弹窗弹出类型Key
  17. NSString * const RQExerciseAlertTypeKey = @"RQExerciseAlertTypeKey";
  18. /// 取消收藏成功通知
  19. NSString * const RQCancelCollectNotification = @"RQCancelCollectNotification";
  20. /// 取消收藏题目Key
  21. NSString * const RQCancelCollectExerciseModelKey = @"RQCancelCollectExerciseModelKey";
  22. /// 取消错题成功通知
  23. NSString * const RQCancelWrongNotification = @"RQCancelWrongNotification";
  24. /// 取消错题题目Key
  25. NSString * const RQCancelWrongExerciseModelKey = @"RQCancelWrongExerciseModelKey";
  26. /// 跳转到下一题通知
  27. NSString * const RQAutoJumpNextNotification = @"RQAutoJumpNextNotification";
  28. NSString * const NYBlockExerciseUpdateNotification = @"NYBlockExerciseUpdateNotification";
  29. @interface RQExerciseModule ()
  30. @property (nonatomic, readwrite, strong) SCLAlertView *alert;
  31. @property (nonatomic, readwrite, strong) UITextView *messageTextView;
  32. @property (nonatomic, readwrite, strong) SCLButton *rePlayButton;
  33. @property (nonatomic, readwrite, strong) SCLButton *closeButton;
  34. /// 考试交卷
  35. @property (nonatomic, readwrite, assign) BOOL handUpIsShow;
  36. /// 考试暂停
  37. @property (nonatomic, readwrite, assign) BOOL suspendIsShow;
  38. /// 考试恢复
  39. @property (nonatomic, readwrite, assign) BOOL resumeIsShow;
  40. @property (nonatomic, readwrite, assign) BOOL isShow;
  41. @end
  42. @implementation RQExerciseModule
  43. static id rq_RQExerciseModule = nil;
  44. #pragma mark - init
  45. + (instancetype)sharedInstance {
  46. static dispatch_once_t onceToken;
  47. dispatch_once(&onceToken, ^{
  48. rq_RQExerciseModule = [[self alloc] init];
  49. });
  50. return rq_RQExerciseModule;
  51. }
  52. - (instancetype)init {
  53. if (self = [super init]) {
  54. [[RQNotificationCenter rac_addObserverForName:UIApplicationDidBecomeActiveNotification object:nil] subscribeNext:^(id x) {
  55. }];
  56. [[RQNotificationCenter rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] subscribeNext:^(id x) {
  57. if (RQ_Exercise_Module.timer) {
  58. [RQ_Exercise_Module.timer setFireDate:[NSDate distantFuture]];
  59. NSDictionary *dic = @{
  60. @"questionArr" : RQ_Exercise_Module.questionArr,
  61. };
  62. [RQ_Exercise_Module showAlertWithRQExerciseAlertType:RQExerciseAlertType_Exam_Resume valueDic:dic confirmAction:^(__kindof QMUIDialogViewController *dialogViewController) {
  63. if (RQ_Exercise_Module.timer) {
  64. [RQ_Exercise_Module.timer setFireDate:[NSDate distantPast]];
  65. }
  66. } cancelAction:nil];
  67. }
  68. }];
  69. }
  70. return self;
  71. }
  72. #pragma mark - PublicMethods
  73. /**
  74. 弹出alertController,并且有多action按钮,分别有处理事件
  75. @param alertType 弹窗类型
  76. @param dic 参数
  77. @param confirmTitle 左边按钮的title
  78. @param cancelTitle 右边按钮的title
  79. @param confirmAction 左边按钮的点击事件
  80. @param cancelAction 右按钮的点击事件
  81. */
  82. - (void)showAlertWithRQExerciseAlertType:(RQExerciseAlertType)alertType valueDic:(NSDictionary * _Nullable )dic confirmAction:(void (^__nullable)(__kindof QMUIDialogViewController * _Nonnull dialogViewController))confirmAction cancelAction:(void (^__nullable)(__kindof QMUIDialogViewController * _Nonnull dialogViewController))cancelAction {
  83. @weakify(self)
  84. if (alertType == RQExerciseAlertType_Exam_Resume) {
  85. if (self.handUpIsShow || self.suspendIsShow) {
  86. return;
  87. }
  88. }
  89. QMUIDialogViewController *dialogViewController = [[QMUIDialogViewController alloc] init];
  90. dialogViewController.headerSeparatorColor = nil;
  91. dialogViewController.headerViewBackgroundColor = UIColor.whiteColor;
  92. dialogViewController.headerViewHeight = (alertType != RQExerciseAlertType_Exam_Suspend)? RQ_FIT_HORIZONTAL(30.f) + 24.f : 0.f;
  93. NSArray *questionArr = @[];
  94. if ([dic.allKeys containsObject:@"questionArr"]) {
  95. if (!RQObjectIsNil(dic[@"questionArr"])) {
  96. questionArr = dic[@"questionArr"];
  97. }
  98. }
  99. NSInteger totalNum = questionArr.count;
  100. NSInteger errorNum = RQ_Exercise_Module.errorArr.count;
  101. NSInteger rightNum = RQ_Exercise_Module.correctArr.count;
  102. NSInteger hasdoNum = errorNum + rightNum;
  103. NSInteger undoNum = totalNum - hasdoNum;
  104. NSInteger perScore = 100 / totalNum;
  105. NSInteger score = rightNum * perScore;
  106. CGFloat progress = (hasdoNum * 1.00) / (totalNum * 1.00);
  107. BOOL isSuccess = (score >= 90);
  108. NSUInteger sec = RQ_Exercise_Module.count%60;
  109. NSUInteger min = RQ_Exercise_Module.count/60;
  110. NSString* sec0,*min0;
  111. sec0 = sec<10 ? @"0" : @"";
  112. min0 = min<10 ? @"0" : @"";
  113. /// 头部区域
  114. QMUILabel *titleLabel = [[QMUILabel alloc] qmui_initWithFont:RQSemiboldFont(21) textColor:RQ_MAIN_TEXT_COLOR_1];
  115. if (alertType == RQExerciseAlertType_Exam_HandUp) {
  116. titleLabel.textColor = RQ_MAIN_TEXT_COLOR_GREEN;
  117. titleLabel.text = @"考试合格";
  118. titleLabel.textColor = RQ_MAIN_TEXT_COLOR_RED;
  119. titleLabel.text = @"考试不合格";
  120. } else if (alertType == RQExerciseAlertType_Exam_Resume) {
  121. titleLabel.textColor = RQ_MAIN_TEXT_COLOR_1;
  122. titleLabel.text = @"为您恢复计时";
  123. } else if (alertType == RQExerciseAlertType_Exam_Konw) {
  124. titleLabel.textColor = RQ_MAIN_TEXT_COLOR_1;
  125. titleLabel.text = @"模考须知";
  126. } else {
  127. titleLabel.textColor = RQ_MAIN_TEXT_COLOR_1;
  128. titleLabel.text = @"";
  129. }
  130. titleLabel.textAlignment = NSTextAlignmentCenter;
  131. if (alertType != RQExerciseAlertType_Exam_Suspend) {
  132. [dialogViewController.headerView addSubview:titleLabel];
  133. [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  134. make.top.mas_offset(24.f);
  135. make.centerX.mas_offset(0);
  136. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH - 80.f, RQ_FIT_HORIZONTAL(30.f)));
  137. }];
  138. }
  139. /// 内容区域
  140. // UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, RQ_SCREEN_WIDTH - 80.f, 36)];
  141. // contentView.backgroundColor = UIColorWhite;
  142. // dialogViewController.contentView = contentView;
  143. if (alertType == RQExerciseAlertType_Exam_HandUp) {
  144. RQExerciseExamAlertView *exerciseExamAlertView = [RQExerciseExamAlertView exerciseExamAlertView];
  145. exerciseExamAlertView.myImageView.image = isSuccess? RQImageNamed(@"及格") : RQImageNamed(@"不及格图");
  146. CGFloat imageHeight = ((RQ_SCREEN_WIDTH - 80.f) * (147.f / 290.f)) * (133.51f / 147.f);
  147. exerciseExamAlertView.frame = CGRectMake(0, 0, RQ_SCREEN_WIDTH - 80.f, 4.f + imageHeight + 16.f + RQ_FIT_HORIZONTAL(60.f) + 24.f);
  148. dialogViewController.contentView = exerciseExamAlertView;
  149. exerciseExamAlertView.myTimeLabel.text = [NSString stringWithFormat:@"剩余时间:%@%lu:%@%lu",min0,(unsigned long)min,sec0,(unsigned long)sec];
  150. exerciseExamAlertView.errorLabel.text = [NSString qmui_stringWithNSInteger:errorNum];
  151. exerciseExamAlertView.unDoLabel.text = [NSString qmui_stringWithNSInteger:undoNum];
  152. exerciseExamAlertView.scoreLabel.text = [NSString qmui_stringWithNSInteger:score];
  153. } else if (alertType == RQExerciseAlertType_Exam_Suspend) {
  154. RQExerciseExamAlertHudView *exerciseExamAlertHudView = [RQExerciseExamAlertHudView exerciseExamAlertHudView];
  155. CGFloat progressWidth = (RQ_SCREEN_WIDTH - 80.f) * (132.f / 290.f);
  156. exerciseExamAlertHudView.frame = CGRectMake(0, 0, RQ_SCREEN_WIDTH - 80.f, 24.f + progressWidth + 16.f + RQ_FIT_HORIZONTAL(24.f) + 24.f);
  157. dialogViewController.contentView = exerciseExamAlertHudView;
  158. [exerciseExamAlertHudView.myProgressView setProgress:progress];
  159. exerciseExamAlertHudView.questionNumLabel.text = [NSString stringWithFormat:@"%ld/%ld题",hasdoNum,totalNum];
  160. exerciseExamAlertHudView.myTimeLabel.text = [NSString stringWithFormat:@"剩余时间:%@%lu:%@%lu",min0,(unsigned long)min,sec0,(unsigned long)sec];
  161. } else if (alertType == RQExerciseAlertType_Exam_Resume) {
  162. RQExerciseExamAlertHudView *exerciseExamAlertHudView = [RQExerciseExamAlertHudView exerciseExamAlertHudView];
  163. CGFloat progressWidth = (RQ_SCREEN_WIDTH - 80.f) * (132.f / 290.f);
  164. exerciseExamAlertHudView.frame = CGRectMake(0, 0, RQ_SCREEN_WIDTH - 80.f, 24.f + progressWidth + 16.f + RQ_FIT_HORIZONTAL(24.f) + 24.f);
  165. dialogViewController.contentView = exerciseExamAlertHudView;
  166. [exerciseExamAlertHudView.myProgressView setProgress:progress];
  167. exerciseExamAlertHudView.questionNumLabel.text = [NSString stringWithFormat:@"%ld/%ld题",hasdoNum,totalNum];
  168. exerciseExamAlertHudView.myTimeLabel.text = [NSString stringWithFormat:@"剩余时间:%@%lu:%@%lu",min0,(unsigned long)min,sec0,(unsigned long)sec];
  169. } else if (alertType == RQExerciseAlertType_Exam_Konw) {
  170. CGFloat textHeight = [@"温馨提示:模拟考试不能修改答案,每错1题扣1分,错题累计超过10道,考试不通过,系统自动提醒交卷。" heightForFont:[UIFont systemFontOfSize:13] width:RQ_SCREEN_WIDTH - 80.f - 24.f - 32.f] + 16.f;
  171. if ([dic.allKeys containsObject:@"questionArr"]) {
  172. if (!RQObjectIsNil(dic[@"questionArr"])) {
  173. questionArr = dic[@"questionArr"];
  174. }
  175. }
  176. RQExerciseExamKnowAlertView *exerciseExamKnowAlertView = [RQExerciseExamKnowAlertView exerciseExamKnowAlertView];
  177. exerciseExamKnowAlertView.frame = CGRectMake(0, 0, RQ_SCREEN_WIDTH - 80.f, 24.f + 104.f + 16.f + textHeight + 24.f);
  178. exerciseExamKnowAlertView.examCarTypeLabel.text = [RQ_YDTQuestion_Module getCarTypeExamNameWithCarType:RQ_YDTQuestion_Module.carType];
  179. switch (RQ_YDTQuestion_Module.carType) {
  180. case RQHomePageCarType_Car:
  181. case RQHomePageCarType_Bus:
  182. case RQHomePageCarType_Truck:
  183. case RQHomePageCarType_Motorcycle:
  184. exerciseExamKnowAlertView.examStandardLabel.text = [NSString stringWithFormat:@"%ld题,45分钟",questionArr.count];
  185. exerciseExamKnowAlertView.examSuccessStandardLabel.text = [NSString stringWithFormat:@"90分及格(满分100)"];
  186. break;
  187. case RQHomePageCarType_ZGZ_JLY:
  188. case RQHomePageCarType_ZGZ_KY:
  189. case RQHomePageCarType_ZGZ_HY:
  190. exerciseExamKnowAlertView.examStandardLabel.text = [NSString stringWithFormat:@"%ld题,60分钟",questionArr.count];
  191. exerciseExamKnowAlertView.examSuccessStandardLabel.text = [NSString stringWithFormat:@"80分及格(满分100)"];
  192. break;
  193. case RQHomePageCarType_ZGZ_WXP:
  194. exerciseExamKnowAlertView.examStandardLabel.text = [NSString stringWithFormat:@"%ld题,60分钟",questionArr.count];
  195. exerciseExamKnowAlertView.examSuccessStandardLabel.text = [NSString stringWithFormat:@"90分及格(满分100)"];
  196. break;
  197. case RQHomePageCarType_ZGZ_CZC:
  198. case RQHomePageCarType_ZGZ_WYC:
  199. exerciseExamKnowAlertView.examStandardLabel.text = [NSString stringWithFormat:@"%ld题,50分钟",questionArr.count];
  200. exerciseExamKnowAlertView.examSuccessStandardLabel.text = [NSString stringWithFormat:@"40分及格(满分50)"];
  201. break;
  202. default:
  203. break;
  204. }
  205. dialogViewController.contentView = exerciseExamKnowAlertView;
  206. }
  207. /// 尾部区域
  208. dialogViewController.footerSeparatorColor = nil;
  209. dialogViewController.footerViewBackgroundColor = UIColor.whiteColor;
  210. dialogViewController.footerViewHeight = RQ_FIT_HORIZONTAL(40.f) + 30.f;
  211. dialogViewController.footerView.hidden = NO;
  212. CGFloat btnWidth = (RQ_SCREEN_WIDTH - 80.f - (16 * 2) - 16) / 2.f;
  213. NSString *confirmTitle = @"确定";
  214. NSString *cancelTitle = @"取消";
  215. if (alertType == RQExerciseAlertType_Exam_HandUp) {
  216. confirmTitle = @"现在交卷";
  217. cancelTitle = @"继续答题";
  218. } else if (alertType == RQExerciseAlertType_Exam_Resume) {
  219. confirmTitle = @"继续答题";
  220. cancelTitle = @"";
  221. } else if (alertType == RQExerciseAlertType_Exam_Suspend) {
  222. confirmTitle = @"继续考试";
  223. cancelTitle = @"重新考试";
  224. } else if (alertType == RQExerciseAlertType_Exam_Konw) {
  225. confirmTitle = @"知道了";
  226. cancelTitle = @"";
  227. } else {
  228. confirmTitle = @"现在交卷";
  229. cancelTitle = @"继续答题";
  230. }
  231. QMUIButton *confirmBtn = [QMUIButton buttonWithType:UIButtonTypeCustom];
  232. [confirmBtn setTitle:confirmTitle textColor:UIColor.whiteColor Font:15 fotState:UIControlStateNormal];
  233. [confirmBtn setBackgroundColor:RQ_MAIN_COLOR];
  234. [confirmBtn setBlockForControlEvents:UIControlEventTouchUpInside block:^(id _Nonnull sender) {
  235. [dialogViewController hide];
  236. @strongify(self)
  237. switch (alertType) {
  238. case RQExerciseAlertType_Exam_HandUp:
  239. self.handUpIsShow = NO;
  240. break;
  241. case RQExerciseAlertType_Exam_Suspend:
  242. self.suspendIsShow = NO;
  243. break;
  244. case RQExerciseAlertType_Exam_Resume:
  245. self.resumeIsShow = NO;
  246. break;
  247. default:
  248. break;
  249. }
  250. if (confirmAction) {
  251. confirmAction(dialogViewController);
  252. }
  253. }];
  254. [dialogViewController.footerView addSubview:confirmBtn];
  255. [confirmBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  256. make.top.mas_offset(0);
  257. if (RQStringIsNotEmpty(cancelTitle)){make.right.mas_offset(-16);} else {make.centerX.mas_offset(0);}
  258. make.size.mas_equalTo(CGSizeMake(btnWidth, RQ_FIT_HORIZONTAL(40.f)));
  259. confirmBtn.layer.cornerRadius = RQ_FIT_HORIZONTAL(40.f) / 2.f;
  260. confirmBtn.layer.masksToBounds = YES;
  261. }];
  262. QMUIButton *cancleBtn = [QMUIButton buttonWithType:UIButtonTypeCustom];
  263. [cancleBtn setTitle:cancelTitle textColor:[UIColor qmui_colorWithHexString:@"#5C6066"] Font:15 fotState:UIControlStateNormal];
  264. cancleBtn.layer.borderColor = [UIColor qmui_colorWithHexString:@"#707070"].CGColor;
  265. cancleBtn.layer.borderWidth = 1;
  266. cancleBtn.layer.cornerRadius = RQ_FIT_HORIZONTAL(40.f) / 2.f;
  267. cancleBtn.layer.masksToBounds = YES;
  268. [cancleBtn setBlockForControlEvents:UIControlEventTouchUpInside block:^(id _Nonnull sender) {
  269. [dialogViewController hide];
  270. @strongify(self)
  271. switch (alertType) {
  272. case RQExerciseAlertType_Exam_HandUp:
  273. self.handUpIsShow = NO;
  274. break;
  275. case RQExerciseAlertType_Exam_Suspend:
  276. self.suspendIsShow = NO;
  277. break;
  278. case RQExerciseAlertType_Exam_Resume:
  279. self.resumeIsShow = NO;
  280. break;
  281. default:
  282. break;
  283. }
  284. if (cancelAction) {
  285. cancelAction(dialogViewController);
  286. }
  287. }];
  288. if (RQStringIsNotEmpty(cancelTitle)) {
  289. [dialogViewController.footerView addSubview:cancleBtn];
  290. [cancleBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  291. make.top.mas_offset(0);
  292. make.left.mas_offset(16);
  293. make.size.mas_equalTo(CGSizeMake(btnWidth, RQ_FIT_HORIZONTAL(40.f)));
  294. }];
  295. }
  296. switch (alertType) {
  297. case RQExerciseAlertType_Exam_HandUp:
  298. self.handUpIsShow = YES;
  299. break;
  300. case RQExerciseAlertType_Exam_Suspend:
  301. self.suspendIsShow = YES;
  302. break;
  303. case RQExerciseAlertType_Exam_Resume:
  304. self.resumeIsShow = YES;
  305. break;
  306. default:
  307. break;
  308. }
  309. [dialogViewController show];
  310. }
  311. - (void)startTimer {
  312. [self.timer invalidate];
  313. self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(_timerValueChanged:) userInfo:nil repeats:YES];
  314. [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
  315. RQ_Exercise_Module.beginDate = [NSDate date];
  316. }
  317. #pragma mark - PrivateMethods
  318. - (void)_timerValueChanged:(NSTimer *)timer {
  319. RQ_Exercise_Module.count --;
  320. if (RQ_Exercise_Module.count == 0) {
  321. [RQ_Exercise_Module.timer invalidate];
  322. RQ_Exercise_Module.timer = nil;
  323. return;
  324. }
  325. }
  326. - (NSInteger)exerciseFontSize {
  327. id object = [RQ_COMMON_MANAGER getObjectWithKey:@"ExerciseFontSize"];
  328. if (RQObjectIsNil(object)) {
  329. return 17;
  330. } else {
  331. NSInteger myExerciseFontSize = [object integerValue];
  332. return myExerciseFontSize;
  333. }
  334. }
  335. - (void)setExerciseFontSize:(NSInteger)exerciseFontSize {
  336. [RQ_COMMON_MANAGER saveObjectWithObject:[NSNumber numberWithInteger:exerciseFontSize] ForKey:@"ExerciseFontSize"];
  337. }
  338. - (BOOL)isRightAutoJumpToNext {
  339. id object = [RQ_COMMON_MANAGER getObjectWithKey:@"isRightAutoJumpToNext"];
  340. if (RQObjectIsNil(object)) {
  341. return NO;
  342. } else {
  343. BOOL myIsRightAutoJumpToNext = [object boolValue];
  344. return myIsRightAutoJumpToNext;
  345. }
  346. }
  347. - (void)setIsRightAutoJumpToNext:(BOOL)isRightAutoJumpToNext {
  348. [RQ_COMMON_MANAGER saveObjectWithObject:[NSNumber numberWithBool:isRightAutoJumpToNext] ForKey:@"isRightAutoJumpToNext"];
  349. }
  350. - (BOOL)isRightAutoRemoveError {
  351. id object = [RQ_COMMON_MANAGER getObjectWithKey:@"isRightAutoRemoveError"];
  352. if (RQObjectIsNil(object)) {
  353. return NO;
  354. } else {
  355. BOOL myIsRightAutoRemoveError = [object boolValue];
  356. return myIsRightAutoRemoveError;
  357. }
  358. }
  359. - (void)setIsRightAutoRemoveError:(BOOL)isRightAutoRemoveError {
  360. [RQ_COMMON_MANAGER saveObjectWithObject:[NSNumber numberWithBool:isRightAutoRemoveError] ForKey:@"isRightAutoRemoveError"];
  361. }
  362. - (BOOL)isExerciseSound {
  363. id object = [RQ_COMMON_MANAGER getObjectWithKey:@"isExerciseSound"];
  364. if (RQObjectIsNil(object)) {
  365. return NO;
  366. } else {
  367. BOOL myIsExerciseSound = [object boolValue];
  368. return myIsExerciseSound;
  369. }
  370. }
  371. - (void)setIsExerciseSound:(BOOL)isExerciseSound {
  372. [RQ_COMMON_MANAGER saveObjectWithObject:[NSNumber numberWithBool:isExerciseSound] ForKey:@"isExerciseSound"];
  373. }
  374. - (NSArray *)questionArr {
  375. if (!_questionArr) {
  376. _questionArr = @[];
  377. }
  378. return _questionArr;
  379. }
  380. - (NSArray *)correctArr {
  381. if (!_correctArr) {
  382. _correctArr = @[];
  383. }
  384. return _correctArr;
  385. }
  386. - (NSArray *)errorArr {
  387. if (!_errorArr) {
  388. _errorArr = @[];
  389. }
  390. return _errorArr;
  391. }
  392. @end