面試問題小結

面試問題:

本次時間:2017-1-6

前言:面試都會遇到各類各樣的人和各類各樣的問題,如下是總結遇到的問題的。大部分的問題都是能夠網上找到答案的。

有的沒有整理完善,等有空了再作更新。
1.get和post的區別ios

Http定義了與服務器交互的不一樣方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE面試

(1)GET使用URL或Cookie傳參。而POST將數據放在BODY中。
(2)GET的URL會有長度上的限制,則POST的數據則能夠很是大。
(3)POST比GET安全,由於數據在地址欄上不可見。sql

具體:數據庫

get請求和post請求均可以用於作獲取數據請求編程

在請求數據安全方面post請求比get請求安全設計模式

get是以明文的方式向服務器發送請求api

post是包裝到請求體body中後,在向服務器發送請求數組

get請求的參數所有暴露在接口中,通常叫作明文請求或者傻瓜式請求,post請求的參數通常是以字典的方式進行拼接,相對於get比較安全安全

若是從服務器獲取數據,或者查詢數據,使用get請求;若是上傳數據到服務器或者修改服務器上傳數據使用post請求服務器

get請求的URL在使用過程當中,會限制長度,所以長度很是長的請求建議用
post請求

對文件大小的請求:get不容許向服務器上傳文件(圖片,pdf,音視頻)

2.runtime機制,具體使用;objc_class的屬性有哪些?在接手同事的一個項目時,使用runtime打印出每個控制器的方法?或者是類別,都知道類別是不能添加屬性的,可是想給它添加成員屬性,runtime怎麼作?

成員變量操做

// 1. 獲取類中指定名稱實例成員變量的信息
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. 獲取整個成員變量列表
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );

屬性操做函數:

// 獲取指定的屬性
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請求數據的時候,在一個頁面須要同時請求多個接口的數據,須要在全部數據都請求成功後才能刷新tableview應該怎麼作?

5.內存管理的基本機制或原理;原則有哪些?

原則:

MRC:
當使用new、alloc或copy方法建立一個對象時,該對象引用計數器爲1。若是不須要使用該對象,能夠向其發送release或autorelease消息,在其使用完畢時被銷燬。

ARC:無效

關鍵字:

  1. assign: 默認修飾符,表示簡單賦值,通常用於(int, char,double,NSInteger等等)類型的基本數據類型.

  2. readonly: 表示"只讀",只會生get方法.

  3. readwrite: 表示"讀寫",會生成set,get方法. 默認修飾符

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

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

  6. copy: 所修飾的成員變量,在對成員變量使用set方法設置值時,會將成員變量將要指向的對象從新複製一份,讓成員變量指向新複製的對象.

    複製一個新的對象.(淺拷貝):字符串、block變量、使用copy
    mutableCopy:複製的是一個指針地址.(深拷貝)

  7. strong: 在arc中做業對象成員的默認修飾符.strong修飾的指針,指向一個對象,對象的引用計數加1.當再也不指向的對象銷燬時,指針會發送release消息.

  8. weak:修飾的指針,指向一個對象,不會retain,當指向的對象被銷燬時,指針會自動變爲nil;weak id delegate block用(copy).
  9. unsafe_unretained,修飾的指針,指向一個對象,不會retain,當指向的對象被銷燬時,指針也不會變爲nil.

6.gcd、建立線程
GCD:是把任務放到隊列中執行
任務:同步、異步;同步是一個一個的執行;異步是能夠同時執行多個
隊列:併發、串行;一個一個的執行是併發;能夠同時多個執行的是串行

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

//用多線程請求網絡數據

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

[self mainThread]; //執行主線程

7.二維碼使用的是第三方仍是本身的,如何解決掃描圖像不清析的問題?

  • 生成二維碼
    • 實例化二維碼濾鏡
    • 恢復濾鏡的默認屬性
    • 將字符串轉換成NSData
    • 經過KVC設置濾鏡inputMessage數據,經過KVC設置濾鏡的 inputCorrectionLevel (容錯率)
    • 得到濾鏡輸出的圖像
    • 將CIImage轉換成UIImage,並放大顯示
    • 經過位圖建立高清圖片
  • 識別二維碼
    • 建立一個上下文
    • 建立一個探測器
    • 轉換原圖片爲 CIImage
    • 獲取探測器識別的圖像特徵
    • 遍歷圖片特徵, 獲取數據
    • 繪製識別到的二維碼邊框
    • 傳遞識別的數據給外界
  • 掃描二維碼
    • 實例化拍攝設備
    • 設置輸入設備
    • 設置元數據輸出處理對象
      • 實例化拍攝元數據輸出
      • 設置輸出數據代理
    • 添加拍攝會話
    • 啓動會話
    • 監聽元數據處理後的結果

8.藍牙技術的問題?

9.https請求的問題?

10.指針問題?

11.設計模式

12.頁面加載的生命週期

  • init-初始化程序
  • viewDidLoad-加載視圖
  • viewWillAppear-UIViewController對象的視圖即將加入窗口時調用;
  • viewDidApper-UIViewController對象的視圖已經加入到窗口時調用;
  • viewWillDisappear-UIViewController對象的視圖即將消失、被覆蓋或是隱藏時調用;
  • viewDidDisappear-UIViewController對象的視圖已經消失、被覆蓋或是隱藏時調用;

13.程序的生命週期

  • Not running: 未運行,程序未啓動
  • Inactive:未激活:程序在前臺運行,不過沒有接收到事件。在沒有事件處理狀況下程序
    一般停留在這個狀態
  • Active: 激活:程序在前臺運行並且接收到了事件。這也是前臺的一個正常的模式
  • Backgroud:後臺:程序在後臺並且能執行代碼,大多數程序進入這個狀態後會在在這個
    狀態上停留一會。時間到以後會進入掛起狀態(Suspended)。有的程序通過
    特殊的請求後能夠長期處於Backgroud狀態
  • Suspended:掛起:程序在後臺不能執行代碼。系統會自動把程序變成這個狀態並且不會
    發出通知。當掛起時,程序仍是停留在內存中的,當系統內存低時,系統就
    把掛起的程序清除掉,爲前臺程序提供更多的內存。
//1. 告訴代理進程啓動但還沒進入狀態保存
- (BOOL)application:(UIApplication *)application 
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions

//2. 告訴代理啓動基本完成程序準備開始運行
- (BOOL)application:(UIApplication *)application
 didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

//3. 當應用程序將要入非活動狀態執行,在此期間,應用程序不接收消息或事件,好比來電話了
- (void)applicationWillResignActive:(UIApplication *)application

//4. 當應用程序入活動狀態執行
- (void)applicationDidBecomeActive:(UIApplication *)application 

//5. 當程序被推送到後臺的時候調用。因此要設置後臺繼續運行,則在這個函數裏面設置便可
- (void)applicationDidEnterBackground:(UIApplication *)application

//6. 當程序從後臺將要從新回到前臺時候調用
- (void)applicationWillEnterForeground:(UIApplication *)application

//7. 當程序將要退出是被調用,一般是用來保存數據和一些退出前的清理工做。這個須要設置UIApplicationExitsOnSuspend的鍵值。 
- (void)applicationWillTerminate:(UIApplication *)application

//8. 當程序載入後執行
- (void)applicationDidFinishLaunching:(UIApplication*)application

14.MVC模式

MVC圖片

Model

  • 模型對象封裝了應用程序的數據,並定義操控和處理該數據的邏輯和運算

View

  • 視圖對象是應用程序中用戶能夠看見的對象。視圖對象知道如何將本身繪製出來,並可能對用戶的操做做出響應

Controller

  • 在應用程序的一個或多個視圖對象和一個或多個模型對象之間,控制器對象充當媒介。控制器對象所以是同步管道程序,經過它,視圖對象瞭解模型對象的更改,反之亦然。

總結:

  • Model和View永遠不能相互通訊,只能經過Controller傳遞。
  • Controller能夠直接與Model對話(讀寫調用Model),Model經過Notification和KVO機制與Controller間接通訊。
  • Controller能夠直接與View對話,經過outlet,直接操做View,outlet直接對應到View中的控件,View經過action向Controller報告事件的發生(如用戶Touch我了)。Controller是View的直接數據源(數據極可能是Controller從Model中取得並通過加工了)。Controller是View的代理(delegate),以同步View與Controller。

15.MVVM模式

16.爲何block使用copy

當用__block來修飾變量int aa = 10 的時候,在block內部調用變量aa的時候,使用的是在相同內存空間中修改過的變量aa的值,即變量aa的值從10修改成了100。那麼此時打印aa獲得的結果就是修改過的值100,且地址仍是開始聲明aa的時候所開闢的內存空間的地址

緣由是:當變量aa未使用__block修飾的時候,block會將「捕捉」到的變量複製一份,而後對複製品進行操做。也就是說預編譯的時候,block已經把變量aa複製了一份出來(能夠理解爲從新聲明瞭一個同名的變量,此時的兩個變量在內存中的地址是不一樣的),當最後一句代碼執行了block調用的時候,block內部使用的是本身複製(本質上是深拷貝)出來的一個變量

17.關於爲何使用weak而不是用assign來對delegate進行標註?
delegate通常的類型都是id,便可以指向全部對象的id類型。因此咱們既可使用assign指向他,也可使用weak指向他。可是由於weak在不被持有的時候會指向nil,全部經過nil的方法在調用函數的時候,都會返回爲nil,這樣就可以保證了程序的穩定性,就算沒有東西返回,他仍是可以正常解析(只是解析出來的值爲nil)。而若是使用assign的話,若是一不持有他。那麼下次再調用它的時候,他將會指向一個不知名的地址,即野指針。這樣就會使得整個程序crash。

18.數據持久化的區別,何時使用哪個效果更好?

分爲四類:
  1. 文件、或是沙盒目錄存儲:分三個目錄
  • DocumentsiTunes同步該應用時會同步此文件夾中的內容,適合存儲重要數據.
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  • Library/Caches: iTunes不會同步此文件夾,適合存儲體積大,不須要備份的非重要數據.
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  • Library/Preferences: iTunes同步該應用時會同步此文件夾中的內容,一般保存應用的設置信息。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  • /tmp: iTunes不會同步此文件夾,系統可能在應用沒運行時就刪除該目錄下的文件,因此此目錄適合保存應用中的一些臨時文件,用完就刪除.
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)

    歸檔(又名序列化),把對象轉爲字節碼,以文件的形式存儲到磁盤上,程序運行過程當中或者再次從新打開程序的時候,能夠經過解歸檔(返序列化)還原這些對象。

  • 歸檔的對象是Foundation框架中的對象
  • 歸檔和解歸檔其中任意對象都須要歸檔和解歸檔整個文件
    歸檔後的文件是加密的,因此歸檔文件的擴展名能夠隨意取
  • 在帶鍵的歸檔中,每一個歸檔都有一個key值,解歸檔時key值要與歸檔時key值匹配
  • 若是一個自定義的類A,做爲另外一個自定義類B的一個屬性存在;那麼,若是要對B進行歸檔,那麼,B要實現NSCoding協議。而且,A也要實現NSCoding協議.
[NSKeyedArchiver archiveRootObject:obj toFile:appSettingPath];//會調用對象的encodeWithCoder方法

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

[NSKeyedUnarchiver unarchiveObjectWithFile:appSettingPath];//會調用對象的initWithCoder方法
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
    _name = [aDecoder decodeObjectForKey:kAddressCardName];
    _emailObj = [aDecoder decodeObjectForKey:kAddressCardEmail];
    _salary = [aDecoder decodeIntegerForKey:kAddressCardSalary];
    return self;
}
3. 屬性列表(NSUserDefaults)

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

  • 應用域(application domain)是最重要的域,它存儲着你app經過NSUserDefaults set...forKey添加的設置。
  • 註冊域(registration domain)僅有較低的優先權,只有在應用域沒有找到值時才從註冊域去尋找。
  • 全局域(global domain)則存儲着系統的設置
  • 語言域(language-specific domains)則包括地區、日期等
  • 參數域(argument domain)有最高優先權
注意:

偏好設置是專門用來保存應用程序的配置信息的,通常不要在偏好設置中保存其餘數據。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"marlonxlj" forKey:@"userName"];
[defaults setInteger:28 forKey:@"Age"];
//同步
[defaults synchronize];
4. 數據庫(SQLite、CoreData、第三方類庫

主要存儲大文件,數據量大的時候採用.

coreData:它使開發者能夠把數據當作對象來操做,而沒必要在意數據在磁盤中的存儲方式。

  • 持久化存儲協調器NSPersistentStoreCoordinator
  • 託管對象模型NSManagedObjectModel
  • 託管對象上下文NSManagedObjectContext
模型文件操做

1.1 建立模型文件,後綴名爲.xcdatamodeld。建立模型文件以後,能夠在其內部進行添加實體等操做(用於表示數據庫文件的數據結構)

1.2 添加實體(表示數據庫文件中的表結構),添加實體後須要經過實體,來建立託管對象類文件。

1.3 添加屬性並設置類型,能夠在屬性的右側面板中設置默認值等選項。(每種數據類型設置選項是不一樣的)

1.4 建立獲取請求模板、設置配置模板等。

1.5 根據指定實體,建立託管對象類文件(基於NSManagedObject的類文件)

實例化上下文對象

2.1 建立託管對象上下文(NSManagedObjectContext)

2.2 建立託管對象模型(NSManagedObjectModel)

2.3 根據託管對象模型,建立持久化存儲協調器(NSPersistentStoreCoordinator)

2.4 關聯並建立本地數據庫文件,並返回持久化存儲對象(NSPersistentStore)

2.5 將持久化存儲協調器賦值給託管對象上下文,完成基本建立。
// 從應用程序包中加載模型文件
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
    // 傳入模型對象,初始化持久化存儲協調器
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    // 構建SQLite數據庫文件的路徑
    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingString:@"person"]];
    // 添加持久化存儲器,用sqlite做爲存儲庫
    NSError *error = nil;
    NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
    if(store == nil)
    {
        [NSException raise:@"添加數據庫失敗" format:@"%@", [error localizedDescription]];
    }
    // 建立託管對象上下文
    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"];
    // 利用上下文對象,將數據同步到持久化存儲庫
    NSError *errorSave = nil;
    BOOL sucess = [context save:&errorSave];
// 從數據庫查詢數據
    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;
    // 執行請求
    NSError *errorFetch = nil;
    NSArray *objs = [context executeFetchRequest:request error:&errorFetch];
    if(errorFetch)
    {
        [NSException raise:@"查詢錯誤" format:@"%@", [errorFetch localizedDescription]];
    }

19.copy、mutableCopy區別?

[對象:copy]
[對象:mutableCopy]

對於不可變對象,copy只是拷貝了對象的地址.mutableCopy纔是拷貝了一個新的對象.
對於可變對象,copy,mutableCopy都是拷貝一個新的對象.

[注]對於自定義類的對象不是隨便就可使用copy,mutableCopy拷貝一個新對象,自定義類必須聽從NSCoping/NSMutableCopy協議.而且實現協議中的copyWithZone:/mutableCopyWithZone:方法.這樣才能夠實現對自定義對象的拷貝.

對於不可變對象,copy是淺拷貝,mutableCopy是深拷貝.
對於可變對象:copy,mutableCopy都是深拷貝.

20.runloop如何喚醒?好比當程序開始運行的時候去檢測一個沙盒目錄的文件
應用場景舉例:主線程的 RunLoop 裏有兩個預置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。這兩個 Mode 都已經被標記爲"Common"屬性。DefaultMode 是 App 平時所處的狀態,TrackingRunLoopMode 是追蹤 ScrollView 滑動時的狀態。當你建立一個 Timer 並加到 DefaultMode 時,Timer 會獲得重複回調,但此時滑動一個TableView時,RunLoop 會將 mode 切換爲 TrackingRunLoopMode,這時 Timer 就不會被回調,而且也不會影響到滑動操做。

CFRunLoopSourceRef 是事件產生的地方。Source有兩個版本:Source0 和 Source1。

• Source0 只包含了一個回調(函數指針),它並不能主動觸發事件。使用時,你須要先調用 CFRunLoopSourceSignal(source),將這個 Source 標記爲待處理,而後手動調用 CFRunLoopWakeUp(runloop) 來喚醒 RunLoop,讓其處理這個事件。
• Source1 包含了一個 mach_port 和一個回調(函數指針),被用於經過內核和其餘線程相互發送消息。這種 Source 能主動喚醒 RunLoop 的線程

CFRunLoopTimerRef 是基於時間的觸發器,它和 NSTimer 是toll-free bridged 的,能夠混用。其包含一個時間長度和一個回調(函數指針)。當其加入到 RunLoop 時,RunLoop會註冊對應的時間點,當時間點到時,RunLoop會被喚醒以執行那個回調。

CFRunLoopObserverRef 是觀察者,每一個 Observer 都包含了一個回調(函數指針),當 RunLoop 的狀態發生變化時,觀察者就能經過回調接受到這個變化。

系統默認註冊了5個Mode:

  1. kCFRunLoopDefaultMode: App的默認 Mode,一般主線程是在這個 Mode 下運行的。
  2. UITrackingRunLoopMode: 界面跟蹤 Mode,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘 Mode 影響。
  3. UIInitializationRunLoopMode: 在剛啓動 App 時第進入的第一個 Mode,啓動完成後就再也不使用。
  4. GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,一般用不到。
  5. kCFRunLoopCommonModes: 這是一個佔位的 Mode,沒有實際做用。

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

objc_getAssociatedObject / objc_setAssociatedObject來訪問和生成關聯對象

#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 中調用 self.name= 與 _name="" 的區別?

self.name =」object」:會調用對象的setName()方法;
name = 「object」:會直接把object賦值給當前對象的name屬性。

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

因爲Objective-C的動態消息傳遞機制,OC中不存在真正意義上的私有方法。
可是若是你不在.h文件中聲明,只在.m文件中實現,或在.m文件的Class Extension裏聲明,那麼基本上和私有方法差很少。

23.MVC是什麼設計模式,你還熟悉什麼設計模式?

MVC是一種複合模式

(1)模型:模型持有全部的數據、狀態和程序邏輯。模型獨立於視圖和控制器。

(2)視圖:用來呈現模型。視圖一般直接從模型中取得它須要顯示的狀態與數據。對於相同的信息能夠有多個不一樣的顯示形式或視圖。

(3)控制器:位於視圖和模型中間,負責接受用戶的輸入,將輸入進行解析並反饋給模型,一般一個視圖具備一個控制器。

設計模式分爲三大類:

1.建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

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

3.行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

4.併發型模式

5.線程池模式。

設計模式的六大原則:

總原則-開閉原則
對擴展開放,對修改封閉。在程序須要進行拓展的時候,不能去修改原有的代碼,而是要擴展原有代碼,實現一個熱插拔的效果。因此一句話歸納就是:爲了使程序的擴展性好,易於維護和升級。
想要達到這樣的效果,咱們須要使用接口和抽象類等,後面的具體設計中咱們會提到這點。

一、單一職責原則
不要存在多於一個致使類變動的緣由,也就是說每一個類應該實現單一的職責,不然就應該把類拆分。

二、里氏替換原則(Liskov Substitution Principle)
任何基類能夠出現的地方,子類必定能夠出現。里氏替換原則是繼承複用的基石,只有當衍生類能夠替換基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也可以在基類的基礎上增長新的行爲。
里氏代換原則是對「開-閉」原則的補充。實現「開閉」原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。里氏替換原則中,子類對父類的方法儘可能不要重寫和重載。由於父類表明了定義好的結構,經過這個規範的接口與外界交互,子類不該該隨便破壞它。

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

四、接口隔離原則(Interface Segregation Principle)
每一個接口中不存在子類用不到卻必須實現的方法,若是否則,就要將接口拆分。使用多個隔離的接口,比使用單個接口(多個接口方法集合到一個的接口)要好。

五、迪米特法則(最少知道原則)(Demeter Principle)
一個類對本身依賴的類知道的越少越好。不管被依賴的類多麼複雜,都應該將邏輯封裝在方法的內部,經過public方法提供給外部。這樣當被依賴的類變化時,才能最小的影響該類。
最少知道原則的另外一個表達方式是:只與直接的朋友通訊。類之間只要有耦合關係,就叫朋友關係。耦合分爲依賴、關聯、聚合、組合等。咱們稱出現爲成員變量、方法參數、方法返回值中的類爲直接朋友。局部變量、臨時變量則不是直接的朋友。咱們要求陌生的類不要做爲局部變量出如今類中。

六、合成複用原則(Composite Reuse Principle)
儘可能首先使用合成/聚合的方式,而不是使用繼承。

24.系統自帶的線程池(NSOpertionQueue)的做用?

凡是須要啓動多個線程的地方均可以使用NSOpertionQueue,加入到NSOpertionQueue中的對象都須要繼承NSOpertion。 NSOpertionQueue會在系統內部啓動一個獨立線程去執行這個被加入對象的main方法。

經常使用的地方是用nsoprationqueue 下載圖片,文件。若是是本身建立一個線程池,無非就是啓動多個線程的時候,

把這些線程對象放到一個大數組中,若是須要啓動線程的時候,先從數組中找空閒線程來使用。

本身管理線程池最大的難題是很差處理當啓動多個線程後,用戶在多個界面的跳轉的時候,對線程方法的回調管理。

而NSOpertionQueue能夠很好的處理他。

25.類別有什麼做用?繼承和類別在實現中有何區別?

category 能夠在不獲悉,不改變原來代碼的狀況下往裏面添加新的方法,只能添加,不能刪除修改。
category:類、種類
而且若是類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,由於類別具備更高的優先級.

類別跟類的優先級

類別主要有3個做用:

(1)將類的實現分散到多個不一樣文件或多個不一樣框架中。

(2)建立對私有方法的前向引用。

(3)向對象添加非正式協議。

繼承能夠增長,修改或者刪除方法,而且能夠增長屬性。

非正式協議:是使用類別category來實現,非正式協議是NSObject的一個類別,這樣任何類的對象均可以做爲委託對象來使用,它能夠列出對象可以執行的全部方法,這樣用來實現委託, 咱們可使用選擇器來判斷該非正式協議中是否有這個方法。

正式協議:是一個命名的方法列表,與非正式協議相比不一樣的是,它要求顯示的採用協議,採用協議的方法是在類的@interface聲明中列出協議的名稱,此時,實現協議的類應該遵照協議,承諾實現協議中的全部方法。

26.ios平臺怎麼作數據的持久化?Coredata和sqlite有無必然聯繫?coredata是一個關係型數據庫嗎?

好比寫入沙盒(實際上是一個本應用程序才能夠訪問的路徑),由於sqlite是c語言的api。 你的問題問的是數據庫相關,好比存到網絡上,還提供了一些管理的功能,好比寫入數據庫,然而有人也須要obj-c 的api,core data不只僅是把c的api翻譯成oc 的api,但從邏輯上又分紅不少種, Core data與sqlite仍是有聯繫的,core data 是對sqlite的封裝,因此有了 core data 另外,使用更加方便數據的持久化本質上都是就是寫文件,那麼針對它討論

27.讓一個物體從界面的一個點到另外一個點,有哪些方法?

28.如下每行代碼執行後,persion對象的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.你在開發項目中時,用到了哪些數據存儲方式,iphone中常見的方式有哪些,各有什麼區別?

數據存儲五種形式的應用範圍和性能區別

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

代碼規範

  • 命名規範
    • 1). 常量的命名
    • 2). 枚舉的命名
    • 3). 變量和對象的命名
  • 編碼規範:三個原則:可複用, 易維護, 可擴展
    • 1). 判斷nil或者YES/NO
    • 2). 條件賦值
    • 3). 初始化方法
    • 4). 定義屬性
    • 5). BOOL賦值
    • 6) 拒絕死值
    • 7). 複雜的條件判斷
    • 8). 嵌套判斷
    • 9). 參數過多
    • 10). 回調方法
  • Block的循環引用問題
    • __wealk

####🐼🐶🐶若是對你有幫助,或以爲能夠。請右上角star一下,這是對我一種鼓勵,讓我知道我寫的東西有人承認,我纔會後續不斷的進行完善。
****
###有任何問題或建議請及時issues me,以便我能更快的進行更新修復。
****
####Email: marlonxlj@163.com

相關文章
相關標籤/搜索