转载

详解 iOS 上机题!附个人见解

详解 iOS 上机题!附个人见解

机试题目如下

用命令行创建一个以CocoaPods管理的项目【Test-你的姓名拼音】,新建3个ViewController,完成以下题目

将下面的问题在一个UITabView里面列出所有问题,单击每一行进入一个新的页面,里面是问题和答案。

1.1 什么是VFL,请说出“H:[_aImageView(==50)]-10-[_aButton]”代表的意思?

1.2 NSPersistentStoreCoordinator/NSManagedObjectContext和NSManagedObject三者什么关系

1.3 ARC下什么时候使用Strong,什么时候使用Weak,如何避免循环引用?

1.4 将一个MRC的项目转换为ARC的项目,应该遵循什么规则?

1.5 Objective-C如何对内存管理的,有哪些情况会导致崩溃,说说你的看法和解决方法?

1.6 简述GCD是如何简化线程编程的?

1.7 Extensions有哪些类型,每种类型可以完成的功能有哪些?

1.8 如何衡量ViewController的规模?

1.9 MVVM是什么,请简述MVVM的特点以及解决了哪些问题?

2.请使用UIScrollerView控件实现图片的循环切换

3.请使用UICollectionView控件实现图片数据绑定,要求每行两列

参考思路

1.新建以CocoaPods管理的项目

在命令行窗口输入以下命令

pod init pod install

等待Updating完毕以后文件夹的样式

详解 iOS 上机题!附个人见解

打开test-cyx.xcworkspace文件

PS:下面只写思路,由于有点强迫症,想把题目做的完整一点,时间又不允许,就只把思路写写就好了

2.第一题(创建一个TableViewController)

1.我们假定问题和答案分别是字典的Key和Value,把十道题目分别存放到一个.plist文件中,使之能从.plist文件中读取

2.根据MVC思想,我们面向模型开发,而不是面向字典开发,因此,我们从plist文件中读出的字典数组需要转化为模型数组

(1)(M)我们需要定义模型test类,里面有两个属性:

@property (nonatomic, copy) NSString *testName;题目

@property (nonatomic, copy) NSString *testContext;答案

(2)(V)创建一个用于展示问题和答案的PageViewController类,.h头文件里向外暴露了@property (nonatomic, strong) YXTest * text;属性

(3)(C)通过TableViewController类里面使用KVC把字典数据转为模型数据,再在以下方法把模型数据传递给PageViewController用于展示。

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{       PageViewController *page = [[PageViewController alloc]init];       page.text = self.text;       [self.navigationController pushViewController:page animated:YES];   }

上面的Demo骨架已经搭完了,下面是解析一下问题的答案(当然,这些问题都可以从网上直接找到答案,这里只是简单说说我个人的理解,如有纰漏,欢迎指正)

  • 什么是VFL,请说出“H:[_aImageView(==50)]-10-[_aButton]”代表的意思?

    • VFL:苹果为了简化手写Autolayout代码发明出来的,好像叫可视化格式语言(表示真的很久没用过啊!自从发现了Masonry),那行代码的意思应该是设置水平方向的约束。

    • 手写Autolayout代码我一般使用第三方框架:Masonry。用Masonry写出来的代码的可读性非常好。

  • NSPersistentStoreCoordinator////NSManagedObjectContext和NSManagedObject三者什么关系

    • CoreData里面的属性,NSPersistentStoreCoordinator:持久性数据协调器;NSManagedObjectModel:管理数据模型;NSManagedObjectContext:管理数据内容。三者的关系:CoreData根据NSManagedObjectModel对象确定如何将底层的持久化文件中的数据映射为NSManagedObject对象。

    • 对于数据持久化的操作,我使用比较多的是通过FMDB框架操作SQLite,因为CoreData是基于OC封装了SQLite,性能并没有SQLite好。例如GCD性能比NSOperation好。

  • ARC下什么时候使用Strong,什么时候使用Weak,如何避免循环引用?

    • ARC下,是Xcode编译器自动判断是否有强指针引用着对象,从而自动帮我们在恰当的位置加上引用计数加一或减一的代码 。使用Strong就表明这个OC对象是被使用强指针引用的。

    • 因此,我们自己定义的需要使用的OC属性(UI控件除外)时,一般使用Strong;UI控件一般使用weak,因为在UI控件通常被父控件的subViews数组强引用着。

    • 首先,循环引用的意思是两个对象互相强引用着(或者多个对象引用循环),造成互相都无法释放,效果类似与‘死锁’。避免循环引用的方式是将其中一个对象设置为weak。我印象比较深的在使用block时造成的循环引用,例如 使用AFN的时候

// 在AFN的block内使用,防止造成循环引用 __weak typeof(self) weakSelf = self; [[AFHTTPSessionManager manager] GET:CYXRequestURL parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {  NSLog(@"请求成功");  // 利用MJExtension框架进行字典转模型  weakSelf.menus = [CYXMenu objectArrayWithKeyValuesArray:responseObject[@"result"]];  // 刷新数据(若不刷新数据会显示不出)  [weakSelf.tableView reloadData]; } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {  NSLog(@"请求失败 原因:%@",error); }]; 
  • 将一个MRC的项目转换为ARC的项目,应该遵循什么规则?

    • (我也不太确定,猜的)规则难道是,需要转换为ARC文件的就转换,,不需要转换的就不转换?过滤掉无需转换的文件(不支持ARC的文件)。无需转换的文件应添加-fno-objc-arc标记

  • Objective-C如何对内存管理的,有哪些情况会导致崩溃,说说你的看法和解决方法?

    • (...上面已经问过ARC了,这题我猜是问iOS系统的内存管理原则了吧?)

    • 当App收到三次内存警告还不做处理时,会造成闪退。

    • 处理方法:在didReceiveMemoryWarning内释放不必要的资源。

  • 简述GCD是如何简化线程编程的?

    • GCD相对于pthread/NSThread,通过自动管理线程的生命周期,从而简化了线程编程。

  • Extensions有哪些类型,每种类型可以完成的功能有哪些?

    • (那时候有几个忘了....)六种类型:Today、Share、Action、Photo Editing、Storage Provider、Custom keyboard

    • 完成的功能可以顾名思义

  • 如何衡量ViewController的规模?

    • -(这个真的不太清楚。。求大神指导)是代码量?业务逻辑的复杂程度?还是ViewController做了过多数据加工的事情,造成ViewController的规模变大?

  • MVVM是什么,请简述MVVM的特点以及解决了哪些问题

    • M(Model)V(View)VM(ViewModel),是一种View层的架构模式,衍生自MVC。

    • 特点:把数据加工的任务从Controller中移到了ViewModel,使得Controller只需要专注于数据调配的工作,ViewModel则去负责数据加工并通过通知机制让View响应ViewModel的改变。

    • 目标:为MVC中的Controller减负

请使用UIScrollerView控件实现图片的循环切换

- CYXInfiniteScrollView.h文件

#import @interface CYXInfiniteScrollView : UIView @property (strong, nonatomic) NSArray *images; @property (weak, nonatomic, readonly) UIPageControl *pageControl; @property (assign, nonatomic, getter=isScrollDirectionPortrait) BOOL scrollDirectionPortrait; @end

- CYXInfiniteScrollView.m文件

#import "CYXInfiniteScrollView.h" static int const ImageViewCount = 3; @interface CYXInfiniteScrollView() @property (weak, nonatomic) UIScrollView *scrollView; @end @implementation CYXInfiniteScrollView - (instancetype)initWithFrame:(CGRect)frame {  if (self = [super initWithFrame:frame]) {   // 滚动视图   UIScrollView *scrollView = [[UIScrollView alloc] init];   scrollView.showsHorizontalScrollIndicator = NO;   scrollView.showsVerticalScrollIndicator = NO;   scrollView.pagingEnabled = YES;   scrollView.bounces = NO;   scrollView.delegate = self;   [self addSubview:scrollView];   self.scrollView = scrollView;   // 图片控件   for (int i = 0; i                            < minDistance) {    minDistance = distance;    page = imageView.tag;   }  }  self.pageControl.currentPage = page; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {  [self updateContent]; } - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {  [self updateContent]; } #pragma mark - 内容更新 - (void)updateContent {  // 设置图片  for (int i = 0; i                   < 0) {    index = self.pageControl.numberOfPages - 1;   } else if (index >= self.pageControl.numberOfPages) {    index = 0;   }   imageView.tag = index;   imageView.image = self.images[index];  }  // 设置偏移量在中间  if (self.isScrollDirectionPortrait) {   self.scrollView.contentOffset = CGPointMake(0, self.scrollView.frame.size.height);  } else {   self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0);  } }                             

请使用UICollectionView控件实现图片数据绑定,要求每行两列

#import "CYXCollectionViewController.h" @interface CYXCollectionViewController () @end @implementation CYXCollectionViewController static NSString * const CYXCell = @"cell"; - (instancetype)init {  // 流水布局  UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];  layout.itemSize = CGSizeMake(150, 150);  layout.minimumLineSpacing = 0;  layout.minimumInteritemSpacing = 20;  layout.sectionInset = UIEdgeInsetsMake(20, 0, 0, 0);  return [self initWithCollectionViewLayout:layout]; } - (void)viewDidLoad {  [super viewDidLoad];  self.collectionView.backgroundColor = [UIColor whiteColor];  // 注册cell  [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier: CYXCell]; } #pragma mark - - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {  return 30; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: CYXCell forIndexPath:indexPath];  UIImageView *view = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"xxx"]];  cell.backgroundView = view;  return cell; } @end 
正文到此结束
Loading...