機試題目如下
用命令行創建一個以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完畢以後文件夾的樣式
打開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編譯器自動判斷是否有強指針引用著對象,從而自動幫我們在恰當的位置加上引用計數加一或減一的代碼
因此,我們自己定義的需要使用的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=?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