面試遇到的問(wèn)題整理

面試問(wèn)題:

本次時(shí)間:2017-1-6

前言:面試都會(huì)遇到各種各樣的人和各種各樣的問(wèn)題,以下是總結(jié)遇到的問(wèn)題的。大部分的問(wèn)題都是可以網(wǎng)上找到答案的。

有的沒(méi)有整理完善,等有空了再做更新。
1.get和post的區(qū)別

Http定義了與服務(wù)器交互的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE

(1)GET使用URL或Cookie傳參。而POST將數(shù)據(jù)放在BODY中。
(2)GET的URL會(huì)有長(zhǎng)度上的限制,則POST的數(shù)據(jù)則可以非常大。
(3)POST比GET安全,因?yàn)閿?shù)據(jù)在地址欄上不可見(jiàn)。

具體:

get請(qǐng)求和post請(qǐng)求都可以用于做獲取數(shù)據(jù)請(qǐng)求

在請(qǐng)求數(shù)據(jù)安全方面post請(qǐng)求比get請(qǐng)求安全

get是以明文的方式向服務(wù)器發(fā)送請(qǐng)求

post是包裝到請(qǐng)求體body中后,在向服務(wù)器發(fā)送請(qǐng)求

get請(qǐng)求的參數(shù)全部暴露在接口中,一般叫做明文請(qǐng)求或者傻瓜式請(qǐng)求,post請(qǐng)求的參數(shù)一般是以字典的方式進(jìn)行拼接,相對(duì)于get比較安全

如果從服務(wù)器獲取數(shù)據(jù),或者查詢數(shù)據(jù),使用get請(qǐng)求;如果上傳數(shù)據(jù)到服務(wù)器或者修改服務(wù)器上傳數(shù)據(jù)使用post請(qǐng)求

get請(qǐng)求的URL在使用過(guò)程中,會(huì)限制長(zhǎng)度,因此長(zhǎng)度非常長(zhǎng)的請(qǐng)求建議用
post請(qǐng)求

對(duì)文件大小的請(qǐng)求:get不允許向服務(wù)器上傳文件(圖片,pdf,音視頻)

2.runtime機(jī)制,具體使用;objc_class的屬性有哪些?在接手同事的一個(gè)項(xiàng)目時(shí),使用runtime打印出每一個(gè)控制器的方法?或者是類別,都知道類別是不能添加屬性的,但是想給它添加成員屬性,runtime怎么做?

成員變量操作

// 1. 獲取類中指定名稱實(shí)例成員變量的信息
Ivar class_getInstanceVariable ( Class cls, const char *name );
 
// 2. 獲取類成員變量的信息
Ivar class_getClassVariable ( Class cls, const char *name );
 
// 3. 添加成員變量
BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );
 
// 4. 獲取整個(gè)成員變量列表
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );

屬性操作函數(shù):

// 獲取指定的屬性
objc_property_t class_getProperty ( Class cls, const char *name );
 
// 獲取屬性列表
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );
 
// 為類添加屬性
BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );
 
// 替換類的屬性
void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );

3.SDWebImage的源碼?他的原理是怎么樣?

4.在使用AFNetworking請(qǐng)求數(shù)據(jù)的時(shí)候,在一個(gè)頁(yè)面需要同時(shí)請(qǐng)求多個(gè)接口的數(shù)據(jù),需要在所有數(shù)據(jù)都請(qǐng)求成功后才能刷新tableview應(yīng)該怎么做?

5.內(nèi)存管理的基本機(jī)制或原理;原則有哪些?

原則:

MRC:
當(dāng)使用new、alloc或copy方法創(chuàng)建一個(gè)對(duì)象時(shí),該對(duì)象引用計(jì)數(shù)器為1。如果不需要使用該對(duì)象,可以向其發(fā)送release或autorelease消息,在其使用完畢時(shí)被銷毀。

ARC:無(wú)效

關(guān)鍵字:

  1. assign: 默認(rèn)修飾符,表示簡(jiǎn)單賦值,一般用于(int, char,double,NSInteger等等)類型的基本數(shù)據(jù)類型.

  2. readonly: 表示"只讀",只會(huì)生get方法.

  3. readwrite: 表示"讀寫",會(huì)生成set,get方法. 默認(rèn)修飾符

  4. setter: 指定set方法的新名字(給set方法起一個(gè)新的名字)

  5. getter: 指定get方法的新名字(給get方法起一個(gè)新的名字)

  6. copy: 所修飾的成員變量,在對(duì)成員變量使用set方法設(shè)置值時(shí),會(huì)將成員變量將要指向的對(duì)象重新復(fù)制一份,讓成員變量指向新復(fù)制的對(duì)象.

復(fù)制一個(gè)新的對(duì)象.(淺拷貝):字符串、block變量、使用copy
mutableCopy:復(fù)制的是一個(gè)指針地址.(深拷貝)

  1. strong: 在arc中作業(yè)對(duì)象成員的默認(rèn)修飾符.strong修飾的指針,指向一個(gè)對(duì)象,對(duì)象的引用計(jì)數(shù)加1.當(dāng)不再指向的對(duì)象銷毀時(shí),指針會(huì)發(fā)送release消息.

  2. weak:修飾的指針,指向一個(gè)對(duì)象,不會(huì)retain,當(dāng)指向的對(duì)象被銷毀時(shí),指針會(huì)自動(dòng)變?yōu)閚il;weak id<Delegate> delegate block用(copy).

  3. unsafe_unretained,修飾的指針,指向一個(gè)對(duì)象,不會(huì)retain,當(dāng)指向的對(duì)象被銷毀時(shí),指針也不會(huì)變?yōu)閚il.

6.gcd、創(chuàng)建線程
GCD:是把任務(wù)放到隊(duì)列中執(zhí)行
任務(wù):同步、異步;同步是一個(gè)一個(gè)的執(zhí)行;異步是可以同時(shí)執(zhí)行多個(gè)
隊(duì)列:并發(fā)、串行;一個(gè)一個(gè)的執(zhí)行是并發(fā);可以同時(shí)多個(gè)執(zhí)行的是串行

dispatch_queue_t queue = dispatch_queue_create("test", nil);//創(chuàng)建一個(gè)隊(duì)列
dispatch_async(queue, ^{//    創(chuàng)建異步線程
    for (int i = 0; i < 100; i++) {
        NSLog(@"多線程6==%d",i);
    }
NSLog(@"多線程");

//用多線程請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)

dispatch_sync(dispatch_get_main_queue(), ^{// 回到主線程
// 一般在主線程更新界面
    });
});

[self mainThread]; //執(zhí)行主線程

7.二維碼使用的是第三方還是自己的,如何解決掃描圖像不清析的問(wèn)題?

  • 生成二維碼
    • 實(shí)例化二維碼濾鏡
    • 恢復(fù)濾鏡的默認(rèn)屬性
    • 將字符串轉(zhuǎn)換成NSData
    • 通過(guò)KVC設(shè)置濾鏡inputMessage數(shù)據(jù),通過(guò)KVC設(shè)置濾鏡的 inputCorrectionLevel (容錯(cuò)率)
    • 獲得濾鏡輸出的圖像
    • 將CIImage轉(zhuǎn)換成UIImage,并放大顯示
    • 通過(guò)位圖創(chuàng)建高清圖片
  • 識(shí)別二維碼

    • 創(chuàng)建一個(gè)上下文
    • 創(chuàng)建一個(gè)探測(cè)器
    • 轉(zhuǎn)換原圖片為 CIImage
    • 獲取探測(cè)器識(shí)別的圖像特征
    • 遍歷圖片特征, 獲取數(shù)據(jù)
    • 繪制識(shí)別到的二維碼邊框
    • 傳遞識(shí)別的數(shù)據(jù)給外界
  • 掃描二維碼

    • 實(shí)例化拍攝設(shè)備

    • 設(shè)置輸入設(shè)備

    • 設(shè)置元數(shù)據(jù)輸出處理對(duì)象

      • 實(shí)例化拍攝元數(shù)據(jù)輸出
      • 設(shè)置輸出數(shù)據(jù)代理
    • 添加拍攝會(huì)話

    • 啟動(dòng)會(huì)話

    • 監(jiān)聽(tīng)元數(shù)據(jù)處理后的結(jié)果

8.藍(lán)牙技術(shù)的問(wèn)題?

9.https請(qǐng)求的問(wèn)題?

10.指針問(wèn)題?

11.設(shè)計(jì)模式

12.頁(yè)面加載的生命周期

  • init-初始化程序
  • viewDidLoad-加載視圖
  • viewWillAppear-UIViewController對(duì)象的視圖即將加入窗口時(shí)調(diào)用;
  • viewDidApper-UIViewController對(duì)象的視圖已經(jīng)加入到窗口時(shí)調(diào)用;
  • viewWillDisappear-UIViewController對(duì)象的視圖即將消失、被覆蓋或是隱藏時(shí)調(diào)用;
  • viewDidDisappear-UIViewController對(duì)象的視圖已經(jīng)消失、被覆蓋或是隱藏時(shí)調(diào)用;

13.程序的生命周期

  • Not running: 未運(yùn)行,程序未啟動(dòng)
  • Inactive:未激活:程序在前臺(tái)運(yùn)行,不過(guò)沒(méi)有接收到事件。在沒(méi)有事件處理情況下程序
    通常停留在這個(gè)狀態(tài)
  • Active: 激活:程序在前臺(tái)運(yùn)行而且接收到了事件。這也是前臺(tái)的一個(gè)正常的模式
  • Backgroud:后臺(tái):程序在后臺(tái)而且能執(zhí)行代碼,大多數(shù)程序進(jìn)入這個(gè)狀態(tài)后會(huì)在在這個(gè)
    狀態(tài)上停留一會(huì)。時(shí)間到之后會(huì)進(jìn)入掛起狀態(tài)(Suspended)。有的程序經(jīng)過(guò)
    特殊的請(qǐng)求后可以長(zhǎng)期處于Backgroud狀態(tài)
  • Suspended:掛起:程序在后臺(tái)不能執(zhí)行代碼。系統(tǒng)會(huì)自動(dòng)把程序變成這個(gè)狀態(tài)而且不會(huì)
    發(fā)出通知。當(dāng)掛起時(shí),程序還是停留在內(nèi)存中的,當(dāng)系統(tǒng)內(nèi)存低時(shí),系統(tǒng)就
    把掛起的程序清除掉,為前臺(tái)程序提供更多的內(nèi)存。
//1. 告訴代理進(jìn)程啟動(dòng)但還沒(méi)進(jìn)入狀態(tài)保存
- (BOOL)application:(UIApplication *)application 
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions

//2. 告訴代理啟動(dòng)基本完成程序準(zhǔn)備開(kāi)始運(yùn)行
- (BOOL)application:(UIApplication *)application
 didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

//3. 當(dāng)應(yīng)用程序?qū)⒁敕腔顒?dòng)狀態(tài)執(zhí)行,在此期間,應(yīng)用程序不接收消息或事件,比如來(lái)電話了
- (void)applicationWillResignActive:(UIApplication *)application

//4. 當(dāng)應(yīng)用程序入活動(dòng)狀態(tài)執(zhí)行
- (void)applicationDidBecomeActive:(UIApplication *)application 

//5. 當(dāng)程序被推送到后臺(tái)的時(shí)候調(diào)用。所以要設(shè)置后臺(tái)繼續(xù)運(yùn)行,則在這個(gè)函數(shù)里面設(shè)置即可
- (void)applicationDidEnterBackground:(UIApplication *)application

//6. 當(dāng)程序從后臺(tái)將要重新回到前臺(tái)時(shí)候調(diào)用
- (void)applicationWillEnterForeground:(UIApplication *)application

//7. 當(dāng)程序?qū)⒁顺鍪潜徽{(diào)用,通常是用來(lái)保存數(shù)據(jù)和一些退出前的清理工作。這個(gè)需要設(shè)置UIApplicationExitsOnSuspend的鍵值。 
- (void)applicationWillTerminate:(UIApplication *)application

//8. 當(dāng)程序載入后執(zhí)行
- (void)applicationDidFinishLaunching:(UIApplication*)application


14.MVC模式

MVC圖片

Model

  • 模型對(duì)象封裝了應(yīng)用程序的數(shù)據(jù),并定義操控和處理該數(shù)據(jù)的邏輯和運(yùn)算

View

  • 視圖對(duì)象是應(yīng)用程序中用戶可以看見(jiàn)的對(duì)象。視圖對(duì)象知道如何將自己繪制出來(lái),并可能對(duì)用戶的操作作出響應(yīng)

Controller

  • 在應(yīng)用程序的一個(gè)或多個(gè)視圖對(duì)象和一個(gè)或多個(gè)模型對(duì)象之間,控制器對(duì)象充當(dāng)媒介??刂破鲗?duì)象因此是同步管道程序,通過(guò)它,視圖對(duì)象了解模型對(duì)象的更改,反之亦然。

總結(jié):

  • Model和View永遠(yuǎn)不能相互通信,只能通過(guò)Controller傳遞。
  • Controller可以直接與Model對(duì)話(讀寫調(diào)用Model),Model通過(guò)Notification和KVO機(jī)制與Controller間接通信。
  • Controller可以直接與View對(duì)話,通過(guò)outlet,直接操作View,outlet直接對(duì)應(yīng)到View中的控件,View通過(guò)action向Controller報(bào)告事件的發(fā)生(如用戶Touch我了)。Controller是View的直接數(shù)據(jù)源(數(shù)據(jù)很可能是Controller從Model中取得并經(jīng)過(guò)加工了)。Controller是View的代理(delegate),以同步View與Controller。

15.MVVM模式

16.為什么block使用copy

當(dāng)用__block來(lái)修飾變量int aa = 10 的時(shí)候,在block內(nèi)部調(diào)用變量aa的時(shí)候,使用的是在相同內(nèi)存空間中修改過(guò)的變量aa的值,即變量aa的值從10修改為了100。那么此時(shí)打印aa得到的結(jié)果就是修改過(guò)的值100,且地址還是開(kāi)始聲明aa的時(shí)候所開(kāi)辟的內(nèi)存空間的地址

原因是:當(dāng)變量aa未使用__block修飾的時(shí)候,block會(huì)將“捕捉”到的變量復(fù)制一份,然后對(duì)復(fù)制品進(jìn)行操作。也就是說(shuō)預(yù)編譯的時(shí)候,block已經(jīng)把變量aa復(fù)制了一份出來(lái)(可以理解為重新聲明了一個(gè)同名的變量,此時(shí)的兩個(gè)變量在內(nèi)存中的地址是不同的),當(dāng)最后一句代碼執(zhí)行了block調(diào)用的時(shí)候,block內(nèi)部使用的是自己復(fù)制(本質(zhì)上是深拷貝)出來(lái)的一個(gè)變量

17.關(guān)于為什么使用weak而不是用assign來(lái)對(duì)delegate進(jìn)行標(biāo)注?
delegate一般的類型都是id,即可以指向所有對(duì)象的id類型。所以我們既可以使用assign指向他,也可以使用weak指向他。但是因?yàn)閣eak在不被持有的時(shí)候會(huì)指向nil,所有通過(guò)nil的方法在調(diào)用函數(shù)的時(shí)候,都會(huì)返回為nil,這樣就能夠保證了程序的穩(wěn)定性,就算沒(méi)有東西返回,他還是能夠正常解析(只是解析出來(lái)的值為nil)。而如果使用assign的話,如果一不持有他。那么下次再調(diào)用它的時(shí)候,他將會(huì)指向一個(gè)不知名的地址,即野指針。這樣就會(huì)使得整個(gè)程序crash。

18.數(shù)據(jù)持久化的區(qū)別,什么時(shí)候使用哪一個(gè)效果更好?

分為四類:
  1. 文件、或是沙盒目錄存儲(chǔ):分三個(gè)目錄
  • DocumentsiTunes同步該應(yīng)用時(shí)會(huì)同步此文件夾中的內(nèi)容,適合存儲(chǔ)重要數(shù)據(jù).
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;

  • Library/Caches: iTunes不會(huì)同步此文件夾,適合存儲(chǔ)體積大,不需要備份的非重要數(shù)據(jù).
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;

  • Library/Preferences: iTunes同步該應(yīng)用時(shí)會(huì)同步此文件夾中的內(nèi)容,通常保存應(yīng)用的設(shè)置信息。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

  • /tmp: iTunes不會(huì)同步此文件夾,系統(tǒng)可能在應(yīng)用沒(méi)運(yùn)行時(shí)就刪除該目錄下的文件,所以此目錄適合保存應(yīng)用中的一些臨時(shí)文件,用完就刪除.
NSString *path = NSTemporaryDirectory();

NSString *filePath = [[self getDocumentPath] stringByAppendingString:@"fileTest.txt"];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"3316368400@qq.com", @"email", @"3316368400@qq.com", @"emailDisplay", nil];
[dictionary writeToFile:filePath atomically:YES];
  1. 歸檔(NSKeyedArchiver)

歸檔(又名序列化),把對(duì)象轉(zhuǎn)為字節(jié)碼,以文件的形式存儲(chǔ)到磁盤上,程序運(yùn)行過(guò)程中或者再次重新打開(kāi)程序的時(shí)候,可以通過(guò)解歸檔(返序列化)還原這些對(duì)象。

  • 歸檔的對(duì)象是Foundation框架中的對(duì)象
  • 歸檔和解歸檔其中任意對(duì)象都需要?dú)w檔和解歸檔整個(gè)文件
    歸檔后的文件是加密的,所以歸檔文件的擴(kuò)展名可以隨意取
  • 在帶鍵的歸檔中,每個(gè)歸檔都有一個(gè)key值,解歸檔時(shí)key值要與歸檔時(shí)key值匹配
  • 如果一個(gè)自定義的類A,作為另一個(gè)自定義類B的一個(gè)屬性存在;那么,如果要對(duì)B進(jìn)行歸檔,那么,B要實(shí)現(xiàn)NSCoding協(xié)議。并且,A也要實(shí)現(xiàn)NSCoding協(xié)議.
[NSKeyedArchiver archiveRootObject:obj toFile:appSettingPath];//會(huì)調(diào)用對(duì)象的encodeWithCoder方法

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:kAddressCardName];
    [aCoder encodeObject:_emailObj forKey:kAddressCardEmail];
    [aCoder encodeInteger:_salary forKey:kAddressCardSalary];
}

[NSKeyedUnarchiver unarchiveObjectWithFile:appSettingPath];//會(huì)調(diào)用對(duì)象的initWithCoder方法
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
    _name = [aDecoder decodeObjectForKey:kAddressCardName];
    _emailObj = [aDecoder decodeObjectForKey:kAddressCardEmail];
    _salary = [aDecoder decodeIntegerForKey:kAddressCardSalary];
    return self;
}

3. 屬性列表(NSUserDefaults)

NSUserDefaults支持基本數(shù)據(jù)類型:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL,NSData.

  • 應(yīng)用域(application domain)是最重要的域,它存儲(chǔ)著你app通過(guò)NSUserDefaults set...forKey添加的設(shè)置。
  • 注冊(cè)域(registration domain)僅有較低的優(yōu)先權(quán),只有在應(yīng)用域沒(méi)有找到值時(shí)才從注冊(cè)域去尋找。
  • 全局域(global domain)則存儲(chǔ)著系統(tǒng)的設(shè)置
  • 語(yǔ)言域(language-specific domains)則包括地區(qū)、日期等
  • 參數(shù)域(argument domain)有最高優(yōu)先權(quán)
注意:

偏好設(shè)置是專門用來(lái)保存應(yīng)用程序的配置信息的,一般不要在偏好設(shè)置中保存其他數(shù)據(jù)。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"marlonxlj" forKey:@"userName"];
[defaults setInteger:28 forKey:@"Age"];
//同步
[defaults synchronize];

4. 數(shù)據(jù)庫(kù)(SQLite、CoreData、第三方類庫(kù)

主要存儲(chǔ)大文件,數(shù)據(jù)量大的時(shí)候采用.

coreData:它使開(kāi)發(fā)者可以把數(shù)據(jù)當(dāng)做對(duì)象來(lái)操作,而不必在乎數(shù)據(jù)在磁盤中的存儲(chǔ)方式。

  • 持久化存儲(chǔ)協(xié)調(diào)器NSPersistentStoreCoordinator
  • 托管對(duì)象模型NSManagedObjectModel
  • 托管對(duì)象上下文NSManagedObjectContext

模型文件操作

1.1 創(chuàng)建模型文件,后綴名為.xcdatamodeld。創(chuàng)建模型文件之后,可以在其內(nèi)部進(jìn)行添加實(shí)體等操作(用于表示數(shù)據(jù)庫(kù)文件的數(shù)據(jù)結(jié)構(gòu))

1.2 添加實(shí)體(表示數(shù)據(jù)庫(kù)文件中的表結(jié)構(gòu)),添加實(shí)體后需要通過(guò)實(shí)體,來(lái)創(chuàng)建托管對(duì)象類文件。

1.3 添加屬性并設(shè)置類型,可以在屬性的右側(cè)面板中設(shè)置默認(rèn)值等選項(xiàng)。(每種數(shù)據(jù)類型設(shè)置選項(xiàng)是不同的)

1.4 創(chuàng)建獲取請(qǐng)求模板、設(shè)置配置模板等。

1.5 根據(jù)指定實(shí)體,創(chuàng)建托管對(duì)象類文件(基于NSManagedObject的類文件)

實(shí)例化上下文對(duì)象

2.1 創(chuàng)建托管對(duì)象上下文(NSManagedObjectContext)

2.2 創(chuàng)建托管對(duì)象模型(NSManagedObjectModel)

2.3 根據(jù)托管對(duì)象模型,創(chuàng)建持久化存儲(chǔ)協(xié)調(diào)器(NSPersistentStoreCoordinator)

2.4 關(guān)聯(lián)并創(chuàng)建本地?cái)?shù)據(jù)庫(kù)文件,并返回持久化存儲(chǔ)對(duì)象(NSPersistentStore)

2.5 將持久化存儲(chǔ)協(xié)調(diào)器賦值給托管對(duì)象上下文,完成基本創(chuàng)建。

// 從應(yīng)用程序包中加載模型文件
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
    // 傳入模型對(duì)象,初始化持久化存儲(chǔ)協(xié)調(diào)器
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    // 構(gòu)建SQLite數(shù)據(jù)庫(kù)文件的路徑
    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingString:@"person"]];
    // 添加持久化存儲(chǔ)器,用sqlite作為存儲(chǔ)庫(kù)
    NSError *error = nil;
    NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
    if(store == nil)
    {
        [NSException raise:@"添加數(shù)據(jù)庫(kù)失敗" format:@"%@", [error localizedDescription]];
    }
    // 創(chuàng)建托管對(duì)象上下文
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    context.persistentStoreCoordinator = psc;
    
NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];
    [card setValue:@"4768558865" forKey:@"no"];
    [person setValue:card forKey:@"card"];
    // 利用上下文對(duì)象,將數(shù)據(jù)同步到持久化存儲(chǔ)庫(kù)
    NSError *errorSave = nil;
    BOOL sucess = [context save:&errorSave];
    
// 從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
    request.sortDescriptors = [NSArray arrayWithObject:sort];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"MJ55*"];
    request.predicate = predicate;
    // 執(zhí)行請(qǐng)求
    NSError *errorFetch = nil;
    NSArray *objs = [context executeFetchRequest:request error:&errorFetch];
    if(errorFetch)
    {
        [NSException raise:@"查詢錯(cuò)誤" format:@"%@", [errorFetch localizedDescription]];
    }

19.copy、mutableCopy區(qū)別?

[對(duì)象:copy]
[對(duì)象:mutableCopy]

對(duì)于不可變對(duì)象,copy只是拷貝了對(duì)象的地址.mutableCopy才是拷貝了一個(gè)新的對(duì)象.
對(duì)于可變對(duì)象,copy,mutableCopy都是拷貝一個(gè)新的對(duì)象.

[注]對(duì)于自定義類的對(duì)象不是隨便就可以使用copy,mutableCopy拷貝一個(gè)新對(duì)象,自定義類必須遵從NSCoping/NSMutableCopy協(xié)議.并且實(shí)現(xiàn)協(xié)議中的copyWithZone:/mutableCopyWithZone:方法.這樣才可以實(shí)現(xiàn)對(duì)自定義對(duì)象的拷貝.

對(duì)于不可變對(duì)象,copy是淺拷貝,mutableCopy是深拷貝.
對(duì)于可變對(duì)象:copy,mutableCopy都是深拷貝.

20.runloop如何喚醒?比如當(dāng)程序開(kāi)始運(yùn)行的時(shí)候去檢測(cè)一個(gè)沙盒目錄的文件
應(yīng)用場(chǎng)景舉例:主線程的 RunLoop 里有兩個(gè)預(yù)置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。這兩個(gè) Mode 都已經(jīng)被標(biāo)記為"Common"屬性。DefaultMode 是 App 平時(shí)所處的狀態(tài),TrackingRunLoopMode 是追蹤 ScrollView 滑動(dòng)時(shí)的狀態(tài)。當(dāng)你創(chuàng)建一個(gè) Timer 并加到 DefaultMode 時(shí),Timer 會(huì)得到重復(fù)回調(diào),但此時(shí)滑動(dòng)一個(gè)TableView時(shí),RunLoop 會(huì)將 mode 切換為 TrackingRunLoopMode,這時(shí) Timer 就不會(huì)被回調(diào),并且也不會(huì)影響到滑動(dòng)操作。

CFRunLoopSourceRef 是事件產(chǎn)生的地方。Source有兩個(gè)版本:Source0 和 Source1。

? Source0 只包含了一個(gè)回調(diào)(函數(shù)指針),它并不能主動(dòng)觸發(fā)事件。使用時(shí),你需要先調(diào)用 CFRunLoopSourceSignal(source),將這個(gè) Source 標(biāo)記為待處理,然后手動(dòng)調(diào)用 CFRunLoopWakeUp(runloop) 來(lái)喚醒 RunLoop,讓其處理這個(gè)事件。
? Source1 包含了一個(gè) mach_port 和一個(gè)回調(diào)(函數(shù)指針),被用于通過(guò)內(nèi)核和其他線程相互發(fā)送消息。這種 Source 能主動(dòng)喚醒 RunLoop 的線程

CFRunLoopTimerRef 是基于時(shí)間的觸發(fā)器,它和 NSTimer 是toll-free bridged 的,可以混用。其包含一個(gè)時(shí)間長(zhǎng)度和一個(gè)回調(diào)(函數(shù)指針)。當(dāng)其加入到 RunLoop 時(shí),RunLoop會(huì)注冊(cè)對(duì)應(yīng)的時(shí)間點(diǎn),當(dāng)時(shí)間點(diǎn)到時(shí),RunLoop會(huì)被喚醒以執(zhí)行那個(gè)回調(diào)。

CFRunLoopObserverRef 是觀察者,每個(gè) Observer 都包含了一個(gè)回調(diào)(函數(shù)指針),當(dāng) RunLoop 的狀態(tài)發(fā)生變化時(shí),觀察者就能通過(guò)回調(diào)接受到這個(gè)變化。

系統(tǒng)默認(rèn)注冊(cè)了5個(gè)Mode:

  1. kCFRunLoopDefaultMode: App的默認(rèn) Mode,通常主線程是在這個(gè) Mode 下運(yùn)行的。
  2. UITrackingRunLoopMode: 界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他 Mode 影響。
  3. UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode,啟動(dòng)完成后就不再使用。
  4. GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode,通常用不到。
  5. kCFRunLoopCommonModes: 這是一個(gè)占位的 Mode,沒(méi)有實(shí)際作用。

20.Category中添加屬性和成員變量的區(qū)別?

objc_getAssociatedObject / objc_setAssociatedObject來(lái)訪問(wèn)和生成關(guān)聯(lián)對(duì)象


#import <UIKit/UIKit.h>

@interface UIImage (XLJName)

@property (nonatomic, copy) NSString *XLJ_imageName;

@end


#import "UIImage+XLJName.h"
#import <objc/runtime.h>

static const void *XLJ_imageNameKey = &XLJ_imageNameKey;

@implementation UIImage (XLJName)

- (NSString *)XLJ_imageName
{
    return objc_getAssociatedObject(self, XLJ_imageNameKey);
}

- (void)setXLJ_imageName:(NSString *)XLJ_imageName
{
    objc_setAssociatedObject(self, XLJ_imageNameKey, XLJ_imageName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

21.iOS 中調(diào)用 self.name= 與 _name="" 的區(qū)別?

self.name =”object”:會(huì)調(diào)用對(duì)象的setName()方法;
name = “object”:會(huì)直接把object賦值給當(dāng)前對(duì)象的name屬性。

22.obj-c有私有方法嗎?私有變量嗎?

由于Objective-C的動(dòng)態(tài)消息傳遞機(jī)制,OC中不存在真正意義上的私有方法。
但是如果你不在.h文件中聲明,只在.m文件中實(shí)現(xiàn),或在.m文件的Class Extension里聲明,那么基本上和私有方法差不多。

23.MVC是什么設(shè)計(jì)模式,你還熟悉什么設(shè)計(jì)模式?

MVC是一種復(fù)合模式

(1)模型:模型持有所有的數(shù)據(jù)、狀態(tài)和程序邏輯。模型獨(dú)立于視圖和控制器。

(2)視圖:用來(lái)呈現(xiàn)模型。視圖通常直接從模型中取得它需要顯示的狀態(tài)與數(shù)據(jù)。對(duì)于相同的信息可以有多個(gè)不同的顯示形式或視圖。

(3)控制器:位于視圖和模型中間,負(fù)責(zé)接受用戶的輸入,將輸入進(jìn)行解析并反饋給模型,通常一個(gè)視圖具有一個(gè)控制器。

設(shè)計(jì)模式分為三大類:

1.創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

2.結(jié)構(gòu)型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

3.行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問(wèn)者模式、中介者模式、解釋器模式。

4.并發(fā)型模式

5.線程池模式。

設(shè)計(jì)模式的六大原則:

總原則-開(kāi)閉原則
對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,而是要擴(kuò)展原有代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。所以一句話概括就是:為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。
想要達(dá)到這樣的效果,我們需要使用接口和抽象類等,后面的具體設(shè)計(jì)中我們會(huì)提到這點(diǎn)。

1、單一職責(zé)原則
不要存在多于一個(gè)導(dǎo)致類變更的原因,也就是說(shuō)每個(gè)類應(yīng)該實(shí)現(xiàn)單一的職責(zé),否則就應(yīng)該把類拆分。

2、里氏替換原則(Liskov Substitution Principle)
任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。里氏替換原則是繼承復(fù)用的基石,只有當(dāng)衍生類可以替換基類,軟件單位的功能不受到影響時(shí),基類才能真正被復(fù)用,而衍生類也能夠在基類的基礎(chǔ)上增加新的行為。
里氏代換原則是對(duì)“開(kāi)-閉”原則的補(bǔ)充。實(shí)現(xiàn)“開(kāi)閉”原則的關(guān)鍵步驟就是抽象化。而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。里氏替換原則中,子類對(duì)父類的方法盡量不要重寫和重載。因?yàn)楦割惔砹硕x好的結(jié)構(gòu),通過(guò)這個(gè)規(guī)范的接口與外界交互,子類不應(yīng)該隨便破壞它。

3、依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)
面向接口編程,依賴于抽象而不依賴于具體。寫代碼時(shí)用到具體類時(shí),不與具體類交互,而與具體類的上層接口交互。

4、接口隔離原則(Interface Segregation Principle)
每個(gè)接口中不存在子類用不到卻必須實(shí)現(xiàn)的方法,如果不然,就要將接口拆分。使用多個(gè)隔離的接口,比使用單個(gè)接口(多個(gè)接口方法集合到一個(gè)的接口)要好。

5、迪米特法則(最少知道原則)(Demeter Principle)
一個(gè)類對(duì)自己依賴的類知道的越少越好。無(wú)論被依賴的類多么復(fù)雜,都應(yīng)該將邏輯封裝在方法的內(nèi)部,通過(guò)public方法提供給外部。這樣當(dāng)被依賴的類變化時(shí),才能最小的影響該類。
最少知道原則的另一個(gè)表達(dá)方式是:只與直接的朋友通信。類之間只要有耦合關(guān)系,就叫朋友關(guān)系。耦合分為依賴、關(guān)聯(lián)、聚合、組合等。我們稱出現(xiàn)為成員變量、方法參數(shù)、方法返回值中的類為直接朋友。局部變量、臨時(shí)變量則不是直接的朋友。我們要求陌生的類不要作為局部變量出現(xiàn)在類中。

6、合成復(fù)用原則(Composite Reuse Principle)
盡量首先使用合成/聚合的方式,而不是使用繼承。

24.系統(tǒng)自帶的線程池(NSOpertionQueue)的作用?

凡是需要啟動(dòng)多個(gè)線程的地方都可以使用NSOpertionQueue,加入到NSOpertionQueue中的對(duì)象都需要繼承NSOpertion。 NSOpertionQueue會(huì)在系統(tǒng)內(nèi)部啟動(dòng)一個(gè)獨(dú)立線程去執(zhí)行這個(gè)被加入對(duì)象的main方法。

常用的地方是用nsoprationqueue 下載圖片,文件。如果是自己創(chuàng)建一個(gè)線程池,無(wú)非就是啟動(dòng)多個(gè)線程的時(shí)候,

把這些線程對(duì)象放到一個(gè)大數(shù)組中,如果需要啟動(dòng)線程的時(shí)候,先從數(shù)組中找空閑線程來(lái)使用。

自己管理線程池最大的難題是不好處理當(dāng)啟動(dòng)多個(gè)線程后,用戶在多個(gè)界面的跳轉(zhuǎn)的時(shí)候,對(duì)線程方法的回調(diào)管理。

而NSOpertionQueue可以很好的處理他。

25.類別有什么作用?繼承和類別在實(shí)現(xiàn)中有何區(qū)別?

category 可以在不獲悉,不改變?cè)瓉?lái)代碼的情況下往里面添加新的方法,只能添加,不能刪除修改。
category:類、種類
并且如果類別和原來(lái)類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來(lái)的方法,因?yàn)轭悇e具有更高的優(yōu)先級(jí).

類別跟類的優(yōu)先級(jí)

類別主要有3個(gè)作用:

(1)將類的實(shí)現(xiàn)分散到多個(gè)不同文件或多個(gè)不同框架中。

(2)創(chuàng)建對(duì)私有方法的前向引用。

(3)向?qū)ο筇砑臃钦絽f(xié)議。

繼承可以增加,修改或者刪除方法,并且可以增加屬性。

非正式協(xié)議:是使用類別category來(lái)實(shí)現(xiàn),非正式協(xié)議是NSObject的一個(gè)類別,這樣任何類的對(duì)象都可以作為委托對(duì)象來(lái)使用,它可以列出對(duì)象能夠執(zhí)行的所有方法,這樣用來(lái)實(shí)現(xiàn)委托, 我們可以使用選擇器來(lái)判斷該非正式協(xié)議中是否有這個(gè)方法。

正式協(xié)議:是一個(gè)命名的方法列表,與非正式協(xié)議相比不同的是,它要求顯示的采用協(xié)議,采用協(xié)議的方法是在類的@interface聲明中列出協(xié)議的名稱,此時(shí),實(shí)現(xiàn)協(xié)議的類應(yīng)該遵守協(xié)議,承諾實(shí)現(xiàn)協(xié)議中的所有方法。

26.ios平臺(tái)怎么做數(shù)據(jù)的持久化?Coredata和sqlite有無(wú)必然聯(lián)系?coredata是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)嗎?

比如寫入沙盒(其實(shí)是一個(gè)本應(yīng)用程序才可以訪問(wèn)的路徑),因?yàn)閟qlite是c語(yǔ)言的api。 你的問(wèn)題問(wèn)的是數(shù)據(jù)庫(kù)相關(guān),比如存到網(wǎng)絡(luò)上,還提供了一些管理的功能,比如寫入數(shù)據(jù)庫(kù),然而有人也需要obj-c 的api,core data不僅僅是把c的api翻譯成oc 的api,但從邏輯上又分成很多種, Core data與sqlite還是有聯(lián)系的,core data 是對(duì)sqlite的封裝,所以有了 core data 另外,使用更加方便數(shù)據(jù)的持久化本質(zhì)上都是就是寫文件,那么針對(duì)它討論

27.讓一個(gè)物體從界面的一個(gè)點(diǎn)到另一個(gè)點(diǎn),有哪些方法?

28.以下每行代碼執(zhí)行后,persion對(duì)象的retaion count是多少?

        Persion *persion = [[Persion alloc] init];
        NSLog(@"1---%lu--= 1", (unsigned long)persion.retainCount);
        [persion retain];
        
        NSLog(@"2---%lu -- = 2", (unsigned long)persion.retainCount);
        
        [persion release];
        NSLog(@"3---%lu --= 1", (unsigned long)persion.retainCount);
        
        [persion release];
        NSLog(@"4---%lu --= 1", (unsigned long)persion.retainCount);

29.你在開(kāi)發(fā)項(xiàng)目中時(shí),用到了哪些數(shù)據(jù)存儲(chǔ)方式,iphone中常見(jiàn)的方式有哪些,各有什么區(qū)別?

數(shù)據(jù)存儲(chǔ)五種形式的應(yīng)用范圍和性能區(qū)別

(core data, sqllite,對(duì)象序列化,文件直接讀寫,NSUserDefault(保存數(shù)據(jù)到temp文件夾中)) 文件直接讀寫 >core data> 對(duì)象序列化> sqllite>NSUserDefault.

代碼規(guī)范

  • 命名規(guī)范
    • 1). 常量的命名
    • 2). 枚舉的命名
    • 3). 變量和對(duì)象的命名
  • 編碼規(guī)范:三個(gè)原則:可復(fù)用, 易維護(hù), 可擴(kuò)展
    • 1). 判斷nil或者YES/NO
    • 2). 條件賦值
    • 3). 初始化方法
    • 4). 定義屬性
    • 5). BOOL賦值
      1. 拒絕死值
    • 7). 復(fù)雜的條件判斷
    • 8). 嵌套判斷
    • 9). 參數(shù)過(guò)多
    • 10). 回調(diào)方法
  • Block的循環(huán)引用問(wèn)題
    • __wealk

####??????如果對(duì)你有幫助,或覺(jué)得可以。請(qǐng)右上角star一下,這是對(duì)我一種鼓勵(lì),讓我知道我寫的東西有人認(rèn)可,我才會(huì)后續(xù)不斷的進(jìn)行完善。


###有任何問(wèn)題或建議請(qǐng)及時(shí)issues me,以便我能更快的進(jìn)行更新修復(fù)。


####Email: marlonxlj@163.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,622評(píng)論 30 472
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,802評(píng)論 11 349
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,564評(píng)論 19 139
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,417評(píng)論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,697評(píng)論 18 399

友情鏈接更多精彩內(nèi)容