iOS知識(shí)點(diǎn)(一)

1. 什么是arc?(arc是為了解決什么問題誕生的?)

  • ARC的全稱是Automatic Reference Counting(自動(dòng)引用計(jì)數(shù))
  • ARC是自iOS 5之后增加的新特性,不需要程序員管理內(nèi)容, 編譯器會(huì)在適當(dāng)?shù)牡胤阶詣?dòng)給我們添加release/retain等代碼(主要針對內(nèi)存泄露)

相關(guān)知識(shí):
1.與ARC相對的是MRC, 手動(dòng)引用計(jì)數(shù), 可以簡稱MRC (Manual Reference Counting) 所有對象的內(nèi)容都需要我們手動(dòng)管理, 需要程序員自己編寫release/retain等代碼
2.ARC的判斷原則:只要沒有強(qiáng)指針指向?qū)ο螅瑢ο缶蜁?huì)被釋放。
(1)強(qiáng)指針:默認(rèn)的情況下,所有的指針都是強(qiáng)指針,關(guān)鍵字strong
(2)弱指針:_ _weak關(guān)鍵字修飾的指針
3.ARC的特點(diǎn)總結(jié):
(1)不允許調(diào)用release,retain,retainCount
(2)允許重寫dealloc,但是不允許調(diào)用[super dealloc]
(3)@property的參數(shù):
Strong:相當(dāng)于原來的retain(適用于OC對象類型),成員變量是強(qiáng)指針
Weak:相當(dāng)于原來的assign,(適用于oc對象類型),成員變量是弱指針
Assign:適用于非OC對象類型(基礎(chǔ)類型)

2. 請解釋以下keywords的區(qū)別: assign vs weak, __block vs__weak

  • weak和assign都是引用計(jì)算不變,兩個(gè)的差別在于,weak用于指針類型,而assign用于簡單的數(shù)據(jù)類型,如int BOOL 等。
  • assign看起來跟weak一樣,其實(shí)不能混用的,assign的變量在釋放后并不設(shè)置為nil(和weak不同),當(dāng)你再去引用時(shí)候就會(huì)發(fā)生錯(cuò)誤,崩潰,EXC_BAD_ACCESS.
  • __block 是通過引用來訪問self的實(shí)例變量,block也是一個(gè)強(qiáng)引用,self被retain,引起循環(huán)引用,用__weak是弱引用,當(dāng)self釋放時(shí),weakSelf已經(jīng)等于nil

相關(guān)知識(shí)
在垃圾回收機(jī)制里面,如果你同時(shí)使用__weak__block來標(biāo)識(shí)一個(gè)變量,那么該block將不會(huì)保證它是一直是有效的。 如果你在實(shí)現(xiàn)方法的時(shí)候使用了block,對象的內(nèi)存管理規(guī)則更微妙:也是(__weak__block區(qū)別:)
(1)如果你通過引用來訪問一個(gè)實(shí)例變量,self會(huì)被retain。
(2)如果你通過值來訪問一個(gè)實(shí)例變量,那么變量會(huì)被retain

擴(kuò)展:NSTimer注意避免循環(huán)引用的地方,需要找個(gè)合適的時(shí)機(jī)和地方來 invalidate timer
在引用計(jì)數(shù)的環(huán)境里面,默認(rèn)情況下當(dāng)你在block里面引用一個(gè)Objective-C對象的時(shí)候,該對象會(huì)被retain。當(dāng)你簡單的引用了一個(gè)對象的實(shí)例變量時(shí),它同樣被retain。但是被__block存儲(chǔ)類型修飾符標(biāo)記的對象變量不會(huì)被retain

3. __block在arc和非arc下含義一樣嗎?

  • 對于非ARC下, 為了防止循環(huán)引用, 我們使用__block來修飾在Block中使用的對象:
  • 對于ARC下, 為了防止循環(huán)引用, 我們使用__weak來修飾在Block中使用的對象。原理就是:ARC中,Block中如果引用了__strong修飾符的自動(dòng)變量,則相當(dāng)于Block對該變量的引用計(jì)數(shù)+1。
    <解決循環(huán)引用問題>
//非ARC
__block typeof(self) weakSelf = self;
self.myBlock = ^(int paramInt){ 
//使用weakSelf訪問self成員
 [weakSelf anotherFunc];
};

4. 使用atomic一定是線程安全的嗎?

  • 當(dāng)然不是。
    atomic在set方法里加了鎖,防止了多線程一直去寫這個(gè)property,造成難以預(yù)計(jì)的數(shù)值, 但這也只是讀寫的鎖定, 線程安全其實(shí)還是差一些。

atomic有個(gè)很大的問題是很慢,要比nonatomic慢20倍。
當(dāng)然最后建議這種數(shù)值數(shù)值變化可以讓服務(wù)器來做

5. 描述一個(gè)你遇到過的retaincycle例子。

  • retain cycle 會(huì)造成內(nèi)存溢出,嚴(yán)重情況會(huì)引起崩潰。一般注意點(diǎn)也不會(huì)發(fā)生,但在網(wǎng)絡(luò)連接比較多的地方就會(huì)不小心出現(xiàn),vc異步的網(wǎng)絡(luò)請求,成功后的block調(diào)用vc,如果此時(shí),用戶已經(jīng)不用此vc了,vc還是沒有釋放。

一個(gè)下拉刷新,那個(gè)view和vc互相強(qiáng)引用,導(dǎo)致了沒釋放。view回去調(diào)用vc的scrollview的contentoffset

6. +(void)load; +(void)initialize;有什么用處?

  • 當(dāng)類對象被引入項(xiàng)目時(shí), runtime 會(huì)向每一個(gè)類對象發(fā)送 load 消息, 并且會(huì)在每一個(gè)類甚至分類被引入時(shí)僅調(diào)用一次,(調(diào)用的順序是父類優(yōu)先于子類, 子類優(yōu)先于分類) 而且每一個(gè)類中的 load 方法都不需要像 viewDidLoad 方法一樣調(diào)用父類的方法.

舉個(gè)例子:
由于 load 方法會(huì)在類被 import 時(shí)調(diào)用一次, 而這時(shí)往往是改變類的行為的最佳時(shí)機(jī). 我在 DKNightVersion 中使用 method swizlling 來修改原有的方法時(shí), 就是在分類 load 中實(shí)現(xiàn)的.

  • initialize 方法和 load 方法有一些不同, 它雖然也會(huì)在整個(gè) runtime 過程中調(diào)用一次, 但是它是在該類的第一個(gè)方法執(zhí)行之前調(diào)用, 也就是說 initialize 的調(diào)用是 <惰性> 的, 它的實(shí)現(xiàn)也與我們在平時(shí)使用的惰性初始化屬性時(shí)基本相同.

我在實(shí)際的項(xiàng)目中并沒有遇到過必須使用這個(gè)方法的情況, 在該方法中主要做 靜態(tài)變量的設(shè)置 并用于 確保在實(shí)例初始化前某些條件必須滿足 .

7. 為什么其他語言里叫函數(shù)調(diào)用,objective-c語言里則是給對象發(fā)消息(或者談下對runtime的理解)

  • 我們在其他語言中比如說: C, Python, Java, C++, Haskell ... 中提到函數(shù)調(diào)用或者方法調(diào)用(面向?qū)ο?/strong>). 函數(shù)調(diào)用是在編譯期就已經(jīng)決定了會(huì)調(diào)用哪個(gè)函數(shù)(方法), 編譯器在編譯期就能檢查出函數(shù)的執(zhí)行是否正確.

**然而 Objective-C(ObjC) 是一門動(dòng)態(tài)的語言, 整個(gè) ObjC 語言都是盡可能的將所有的工作推遲到運(yùn)行時(shí)才決定. 它基于 runtime 來工作, runtime 就是 ObjC 的靈魂, 其核心就是消息發(fā)送 objc_msgSend **

  • 所有的消息都會(huì)在運(yùn)行時(shí)才會(huì)確定,[obj message]在運(yùn)行時(shí)會(huì)被轉(zhuǎn)化為objc_msgSend(id self, SEL cmd, ...)來執(zhí)行, 它會(huì)在運(yùn)行時(shí)從 選擇子表中尋找對應(yīng)的選擇子 并將選擇子與實(shí)現(xiàn)進(jìn)行綁定. 而如果沒有找到對應(yīng)的實(shí)現(xiàn), 就會(huì)進(jìn)入類似黑魔法的消息轉(zhuǎn)發(fā)流程. 調(diào)用 + (BOOL)resolveInstanceMethod:(SEL)aSelector方法, 我們可以在這個(gè)方法中 為類動(dòng)態(tài)地生成方法 .

我們幾乎可以使用 runtime 修改 Objective-C 中的一切:
*class property object ivar method protocol *

8. 什么是methodswizzling?

  • method swizzling 實(shí)際上就是一種在運(yùn)行時(shí)動(dòng)態(tài)修改原有方法的技術(shù), 它實(shí)際上是基于 ObjC runtime的特性, 而 method swizzling 的核心方法就是 method_exchangeImplementations(SEL origin, SEL swizzle)使用這個(gè)方法就可以在運(yùn)行時(shí)動(dòng)態(tài)地改變原有的方法實(shí)現(xiàn)

在DKNigtVersion (為iOS應(yīng)用添加夜間模式) 中能夠看到大量 method swizzling 的使用, 方法的調(diào)用時(shí)機(jī)就是在上面提到的 load 方法中, 不在 initialize 方法中改變方法實(shí)現(xiàn)的原因是 initialize 可能會(huì)被子類所繼承并重新執(zhí)行最終導(dǎo)致錯(cuò)誤 , 而 load 并不會(huì)被繼承并重新執(zhí)行.

9. UIView和CALayer是啥關(guān)系?

  • 每一個(gè) UIView 的身后對應(yīng)一個(gè) Core Animation 框架中的 CALayer.

在 iOS 上 當(dāng)你處理一個(gè)一個(gè)有一個(gè)的 UIView 時(shí)實(shí)際上是在操作 CALayer . 盡管有的時(shí)候你并不知道 (直接操作 CALayer 并不會(huì)在對效率有著顯著的提升).

  • UIView 實(shí)際上就是對 CALayer 的輕量級(jí)的封裝. UIView 繼承自 UIResponder 處理來自用戶的事件; CALayer 繼承自 NSObject 主要用于圖層的渲染和動(dòng)畫. 設(shè)計(jì)原因:

1.你可以通過操作 UIView 在一個(gè)更高的層級(jí)上處理與用戶的交互, 觸摸, 點(diǎn)擊, 拖拽等事件, 這些都是在 UIKit 這個(gè)層級(jí)上完成的.
2.UIView 和 NSView(AppKit) 的實(shí)現(xiàn)極其不同, 而使用 Core Animation 可以實(shí)現(xiàn)底層代碼地重用, 因?yàn)樵?Mac 和 iOS 平臺(tái)上都使用著近乎相同的 Core Animation 代碼, 這樣我們可以對這個(gè)層級(jí)進(jìn)行抽象在兩種平臺(tái)上產(chǎn)生 UIKit 和 AppKit 用于不同平臺(tái)的框架.
3.使用 CALayer 的唯一原因大概是便于移植到不同的平臺(tái), 如果僅僅使用 Core Animation 層級(jí), 處理用戶的交互時(shí)間需要寫更多的代碼.

10. 如何高性能的給UIImageView加個(gè)圓角?
(不準(zhǔn)說layer.cornerRadius!)

  • 一般情況下給 UIImageView 或者說 UIKit 的控件添加圓角都是改變 clipsToBounds 和 layer.cornerRadius, 這樣大約兩行代碼就可以解決. 但是, 這樣使用這樣的方法會(huì) 強(qiáng)制 Core Animation提前渲染屏幕的離屏繪制 , 而離屏繪制就會(huì)為性能帶來負(fù)面影響.

<貝塞爾曲線> 可以完美解決

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];  
imageView.center = CGPointMake(200, 300);  
UIImage *anotherImage = [UIImage imageNamed:@"image"];  
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);  
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
  cornerRadius:50] addClip];
[anotherImage drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();  
UIGraphicsEndImageContext();  
[self.view addSubview:imageView];

11. 使用drawRect有什么影響?(這個(gè)可深可淺,你至少得用過。。)

  • 這個(gè)方法的主要作用是根據(jù)傳入的 rect 來繪制圖像,我們還可以在這個(gè)方法中使用 Core Graphics 和 UIKit 來繪制視圖的內(nèi)容.

  • 這個(gè)方法的調(diào)用機(jī)制也是非常特別. 當(dāng)你調(diào)用 setNeedsDisplay 方法時(shí), UIKit 將會(huì)把當(dāng)前圖層標(biāo)記為 dirty, 但還是會(huì)顯示原來的內(nèi)容, 直到下一次的視圖渲染周期, 才會(huì)重新建立 Core Graphics 上下文, 然后將內(nèi)存中的數(shù)據(jù)恢復(fù)出來, 使用 CGContextRef 進(jìn)行繪制.

12. ASIHttpRequest或者SDWebImage里面給
UIImageView加載圖片的邏輯是什么樣的?(把
UIImageView放到UITableViewCell里面問更贊)

  • SDWebImage 中為 UIView 提供了一個(gè)分類叫做 WebCache, 這個(gè)分類中有一個(gè)最常用的接口, sd_setImageWithURL:placeholderImage: , 這個(gè)分類同時(shí)提供了很多類似的方法, 這些方法最終會(huì)調(diào)用一個(gè)同時(shí)具有 optionprogressBlockcompletionBlock 的方法, 而在這個(gè)類最終被調(diào)用的方法首先會(huì)檢查是否傳入了placeholderImage以及對應(yīng)的參數(shù),并設(shè)置
    placeholderImage

  • 然后獲取SDWebImageManager中的單例調(diào)用一個(gè)

    •          ``downloadImageWithURL:...``  的方法來獲取圖片, 而這個(gè)manager 獲取圖片的過程有大體上分為兩部分:
      

首先會(huì)在 SDWebImageCache 中尋找圖片是否有對應(yīng)的緩存, 它會(huì)以 url 作為數(shù)據(jù)的索引先在內(nèi)存中尋找是否有對應(yīng)的緩存, 如果緩存未命中就會(huì)在磁盤中利用 MD5 處理過的 key 來繼續(xù)查詢對應(yīng)的數(shù)據(jù), 如果找到了, 就會(huì)把磁盤中的緩存?zhèn)浞莸絻?nèi)存中.

然而, 假設(shè)我們在內(nèi)存和磁盤緩存中都沒有命中, 那么manager就會(huì)調(diào)用 SDWebImageDownloader 對象的方法downloadImageWithURL:...來下載圖片, 過程中調(diào)用另一個(gè)方法:
addProgressCallback:andCompletedBlock:fotURL:createCallback:來存儲(chǔ)下載過程中和下載完成的回調(diào), 當(dāng)回調(diào)塊是第一次添加的時(shí)候, 方法會(huì)實(shí)例化一個(gè) NSMutableURLRequest 和 SDWebImageDownloaderOperation , 并將后者加入 downloader 持有的下載隊(duì)列開始圖片的異步下載.

  • 而在圖片下載完成之后, 就會(huì)在主線程設(shè)置 image, 完成整個(gè)圖像的異步下載和配置.

13. 麻煩你設(shè)計(jì)個(gè)簡單的圖片內(nèi)存緩存器(移除策略是一定要說的)

圖片的內(nèi)存緩存,可以考慮將圖片數(shù)據(jù)保存到一個(gè)數(shù)據(jù)模型中。所以在程序運(yùn)行時(shí)這個(gè)模型都存在內(nèi)存中。
移除策略:釋放數(shù)據(jù)模型對象。

14. 講講你用Instrument優(yōu)化動(dòng)畫性能的經(jīng)歷吧(別問我什么是Instrument)

考慮程序的性能,可以借助數(shù)據(jù)化圖形化的輸出方式。與其花費(fèi)時(shí)間在優(yōu)化小細(xì)節(jié)上不如多點(diǎn)時(shí)間找到你改優(yōu)化的地方.時(shí)間事件查看器 ——> Time Profiler打開Instrument的步驟:xcode ——> open developer Tool ——> instrument 選取相應(yīng)的strumnet的工具,選擇相應(yīng)的strument里面的工具,然后選擇模擬器或者真機(jī)上面的應(yīng)用,點(diǎn)擊右上角的開始按鈕,然后就可以看到相應(yīng)內(nèi)容

Instrument詳細(xì)介紹

15. loadView是干嘛用的?

  • 當(dāng)你訪問一個(gè)ViewController的view屬性時(shí),如果此時(shí)view的值是nil,那么,ViewController就會(huì)自動(dòng)調(diào)用loadView這個(gè)方法。這個(gè)方法就會(huì)加載或者創(chuàng)建一個(gè)view對象,賦值給view屬性。

loadView默認(rèn)做的事情是:如果此ViewController存在一個(gè)對應(yīng)的nib文件,那么就加載這個(gè)nib。否則,就創(chuàng)建一個(gè)UIView對象。
如果你用Interface Builder來創(chuàng)建界面,那么不應(yīng)該重載這個(gè)方法。
如果你想自己創(chuàng)建view對象,那么可以重載這個(gè)方法。此時(shí)你需要自己給view屬性賦值。你自定義的方法不應(yīng)該調(diào)用super。如果你需要對view做一些其他的定制操作,在viewDidLoad里面去做。

  • 根據(jù)上面可以知道,有兩種情況:

1、如果你用了nib文件,重載這個(gè)方法就沒有太大意義。因?yàn)閘oadView的作用就是加載nib。如果你重載了這個(gè)方法不調(diào)用super,那么nib文件就不會(huì)被加載。如果調(diào)用了super,那么view已經(jīng)加載完了,你需要做的其他事情在viewDidLoad里面做更合適。
2、如果你沒有用nib,這個(gè)方法默認(rèn)就是創(chuàng)建一個(gè)空的view對象。如果你想自己控制view對象的創(chuàng)建,例如創(chuàng)建一個(gè)特殊尺寸的view,那么可以重載這個(gè)方法,自己創(chuàng)建一個(gè)UIView對象,然后指定 self.view = myView; 但這種情況也沒有必要調(diào)用super,因?yàn)榉凑阋膊恍枰趕uper方法里面創(chuàng)建的view對象。如果調(diào)用了super,那么就是浪費(fèi)了一些資源而已

16. viewWillLayoutSubView你總是知道的。

橫豎屏切換的時(shí)候,系統(tǒng)會(huì)響應(yīng)一些函數(shù),其中
viewWillLayoutSubviews 和 viewDidLayoutSubviews。

- (void)viewWillLayoutSubviews  {   
   [self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];  
}  
-(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation {  
   if (orientation == UIDeviceOrientationPortrait ||orientation ==UIDeviceOrientationPortraitUpsideDown) {
// 豎屏 }
 else {
// 橫屏     } 
}
- (NSUInteger)supportedInterfaceOrientations{
    // 切換橫屏
    return UIInterfaceOrientationMaskLandscape;
}

通過上述一個(gè)函數(shù)就知道橫豎屏切換的接口了。
注意:viewWillLayoutSubviews只能用在ViewController里面,在view里面沒有響應(yīng)。

17. GCD里面有哪幾種Queue?你自己建立過串行queue嗎?背后的線程模型是什么樣的?

  • 1.主隊(duì)列 dispatch_main_queue(); 串行 ,更新UI
    2.全局隊(duì)列 dispatch_global_queue(); 并行,四個(gè)優(yōu)先級(jí):background,low,default,high
    3.自定義隊(duì)列 dispatch_queue_t queue ; 可以自定義是并行:DISPATCH_QUEUE_CONCURRENT
    或者串行DISPATCH_QUEUE_SERIAL

18. 用過coredata或者sqlite嗎?讀寫是分線程的嗎?遇到過死鎖沒?咋解決的?

  • 數(shù)據(jù)庫讀取操作一般都是多線程訪問的。在對數(shù)據(jù)進(jìn)行讀取時(shí),我們要保證其當(dāng)前狀態(tài)不能被修改,即讀取時(shí)加鎖,否則就會(huì)出現(xiàn)數(shù)據(jù)錯(cuò)誤混亂。
    IOS中常用的兩種數(shù)據(jù)持久化存儲(chǔ)方式:CoreData和SQLite,兩者都需要設(shè)置線程安全

19. http的post和get啥區(qū)別?(區(qū)別挺多的,麻煩多說點(diǎn))

GET和POST與數(shù)據(jù)如何傳遞沒有關(guān)系, GET和POST是由HTTP協(xié)議定義的。在HTTP協(xié)議中,Method和Data(URL, Body, Header)是正交的兩個(gè)概念,也就是說,使用哪個(gè)Method與應(yīng)用層的數(shù)據(jù)如何傳輸是沒有相互關(guān)系的。HTTP沒有要求,如果Method是POST數(shù)據(jù)就要放在BODY中。也沒有要求,如果Method是GET,數(shù)據(jù)(參數(shù))就一定要放在URL中而不能放在BODY中.

  • 1.(1) GET請求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送,如果是空格,轉(zhuǎn)換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號(hào)以16進(jìn)制表示的ASCII。
    (2) POST把提交的數(shù)據(jù)則放置在是HTTP包的包體中。
  • 2 . HTTP協(xié)議對GET和POST都沒有對長度的限制

(1).首先是”GET方式提交的數(shù)據(jù)是有字節(jié)限制的”,因?yàn)镚ET是通過URL提交數(shù)據(jù),那么GET可提交的數(shù)據(jù)量就跟URL的長度有直接關(guān)系了。其限制取決于操作系統(tǒng)的支持。
  注意這是限制是整個(gè)URL長度,而不僅僅是你的參數(shù)值數(shù)據(jù)長度。
 (2).理論上講,POST是沒有大小限制的,HTTP協(xié)議規(guī)范也沒有進(jìn)行大小限制,POST數(shù)據(jù)是沒有限制的,起限制作用的是服務(wù)器的處理程序的處理能力。

  • 3.POST的安全性要比GET的安全性高,其實(shí)沒有絲毫關(guān)系。對于GET和POST的理解,是純粹地來源于HTTP協(xié)議。他們只有一點(diǎn)根本區(qū)別,簡單點(diǎn)兒說,一個(gè)用于獲取數(shù)據(jù),一個(gè)用于修改數(shù)據(jù)

20. 我知道你大學(xué)畢業(yè)過后就沒接觸過算法數(shù)據(jù)結(jié)構(gòu)了,但是請你一定告訴我什么是Binary search tree? search的時(shí)間復(fù)雜度是多少?我很想知道!

  • Binary search tree:二叉搜索樹。
    主要由四個(gè)方法:(用C語言實(shí)現(xiàn)或者Python)
    1.search:時(shí)間復(fù)雜度為O(h),h為樹的高度
    2.traversal:時(shí)間復(fù)雜度為O(n),n為樹的總結(jié)點(diǎn)數(shù)。
    3.insert:時(shí)間復(fù)雜度為O(h),h為樹的高度。
    4.delete:最壞情況下,時(shí)間復(fù)雜度為O(h)+指針的移動(dòng)開銷。

可以看到,二叉搜索樹的dictionary operation的時(shí)間復(fù)雜度與樹的高度h相關(guān)。所以需要盡可能的降低樹的高度,由此引出平衡二叉樹Balanced binary tree。它要求左右兩個(gè)子樹的高度差的絕對值不超過1,并且左右兩個(gè)子樹都是一棵平衡二叉樹。這樣就可以將搜索樹的高度盡量減小。常用算法有紅黑樹、AVL、Treap、伸展樹等。

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

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

  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒有APIManager這一層是沒法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,491評論 1 23
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,628評論 30 472
  • 基礎(chǔ) 1. 為什么說Objective-C是一門動(dòng)態(tài)的語言? 2. 講一下MVC和MVVM,MVP? 3. 為...
    波妞和醬豆子閱讀 3,547評論 0 46
  • 1.屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作...
    曾令偉閱讀 1,131評論 0 10
  • cookie cookie是什么?用來保存用戶信息 自動(dòng)登錄、記住用戶名 cookie的特性 1.同一個(gè)網(wǎng)站所有頁...
    pizan閱讀 299評論 0 0

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