iOS學習中有關的oc中的所有的知識點

C和OC對比

OC中主要開發在什麼平臺上的應用程序?
答:可以使用OC開發Mac OS X平臺和iOS平臺的應用程序

OC中新增關鍵字大部分是以什麼開頭?
答:OC中新增關鍵字大部分是以@開頭

OC中新增加了那些數據類型?
答:Block類型
指針類型(Class, id類型)
空類型
特殊類型(SEL, nil)

面向對象特性是什麼?
答:繼承性,封裝性,多態性
import和#include有什麼區別?

答:import 的功能和 include一樣, 是將右邊的文件拷貝到當前import的位置.爲了降低程序員的負擔, 防止重複導入, 避免程序員去書寫 頭文件衛士, 那麼OC給出來一個新的預處理指令import
import優點: 會自動防止重複拷貝

printf和NSLog有什麼區別?
答: NSLog會自動換行
NSLog在輸出內容時會附加一些系統信息
NSLog和printf接收的參數不一樣

Foundation有什麼作用?
答:Foundation.h我們稱之爲主頭文件, 主頭文件中又拷貝了該工具箱中所有工具的頭文件, 我們只需要導入主頭文件就可以使用該工具箱中所有的工具, 避免了每次使用都要導入一個對應的頭文件

面向對象基本概念

什麼是面向對象?
答:對象是人們要進行研究的任何事物,從最簡單的整數到複雜的飛機等均可看作對象,它不僅能表示具體的事物,還能表示抽象的規則、計劃或事件。

面向對象和麪向過程的區別?
答:
1>面向對象是相對面向過程而言
2>面向對象和麪向過程都是一種思想
面向過程
強調的是功能行爲
關注的是解決問題需要哪些步驟
面向對象
將功能封裝進對象,強調具備了功能的對象
關注的是解決問題需要哪些對象

類與對象

什麼是對象?
答:對象是人們要進行研究的任何事物,從最簡單的整數到複雜的飛機等均可看作對象,它不僅能表示具體的事物,還能表示抽象的規則、計劃或事件。

什麼是類?
答:具有相同特性(數據元素)和行爲(功能)的對象的抽象就是類。因此,對象的抽象是類,類的具體化就是對象,也可以說類的實例是對象,類實際上就是一種數據類型。

類由幾部分組成?
答: 類(Class) 一個類由3個部分構成
類的名稱:類名
類的屬性:一組包含數據的屬性
類的方法:允許對屬性中包含的數據進行操作的方法

怎麼來定義一個類?書寫類的格式
答:定義類要分爲兩部分: 聲明和實現

類的聲明格式
@interface 類名 : 父類名(NSObject)
{
定義實例變量(成員變量,屬性)
}
方法的聲明

@end

類的實現格式
@implementation 類名
方法的具體實現
@end;

5.OC中屬性寫在類中哪個位置?
答:OC類聲明中屬性只能在寫@interface和@end之間的{}中

6.如何通過類創建對象?書寫創建對象格式
答: 創建對象格式:
類名 *指針名 = [類名 new];

7.實例化對象調用哪個方法?實例化對象做了哪3件事?
答:實例化對象調用類方法new
1.給對象分配存儲空間
2.初始化類中的實力變量
3.返回對象內存地址

8.如何訪問對象中的屬性?
答:使用指針訪問
格式: 指針名->_屬性名;
OC方法

方法和函數的區別?
答:
1)OC中的行爲和C語言中的函數一樣, 都是用來保存一段特定功能的代碼
C語言中定義一個函數, 分爲聲明和實現, 聲明寫在.h中, 實現寫在.c中
OC中定義一個方法, 也分爲聲明和實現, 聲明寫在@interface中, 實現寫在@implementation

C語言的函數分爲兩種: 內部函數和外部函數
OC中的方法也分爲兩種; 類方法和對象方法

怎麼聲明和實現無參無返回值方法的?調用方法的格式?(書寫格式)
答:
方法的聲明格式:
(返回值類型)方法名;
方法的實現格式:

(返回值類型)方法名{
}
調用方法格式:
[對象名 方法名];
或者 [類名 方法名];

小括號在OC方法中有什麼用法?
答:OC方法中的()有特殊的用途, OC方法中的()是用來擴住數據類型的

有參數方法格式是怎樣?
帶一個參數
方法聲明
·- (返回值類型)方法名:(參數類型)參數名;

方法實現
- (返回值類型)方法名:(參數類型)參數名{

}

帶多個參數
方法聲明
- (返回值類型)方法名1:(參數類型)參數名1 方法名2:(參數類型)參數名2;
- (返回值類型)方法名1:(參數類型)參數名1 and方法名2:(參數類型)參數名
- (返回值類型)方法名1:(參數類型)參數名1 :(參數類型)參數名2;
方法實現
- (返回值類型)方法名1:(參數類型)參數名1 方法名2:(參數類型)參數名2{
}
OC類方法

類方法和對象方法的區別?
答:
0). 對象方法以-開頭
類方法以+開頭
1). 對象方法必須用對象調用
類方法必須用類來調用
2).對象方法中可以直接訪問屬性(成員變量)
類方法中不可以直接訪問屬性(成員變量)
3). 類方法和對象方法可以進行相互調用(展示代碼)

類方法的應用場景?
答:
類方法一般用於定義工具方法
字符串查找
文件操作
數據庫操作

isa是什麼數據類型?
答: 類的第0個屬性並不是我們編寫的_age, 而是一個叫做isa的屬性
isa是對象中的隱藏指針,指向創建這個對象的類,佔8個字節

方法和函數的區別

函數和方法的區別?
答:
1).函數屬於整個文件, 方法屬於某一個類
方法如果離開類就不行
2).函數可以直接調用, 方法必須用對象或者類來調用
注意: 雖然函數屬於整個文件, 但是如果把函數寫在類的聲明中會不識別
3).不能把函數當做方法來調用, 也不能把方法當做函數來調用

方法有哪些的注意點?
答:

    方法可以沒有聲明只有實現
    方法可以只有聲明沒有實現, 編譯不會報錯, 但是運行會報錯
    如果方法只有聲明沒有實現, 那麼運行時會報:
    reason: ‘+[Person demo]: unrecognized selector sent to class 0x100001140’
    發送了一個不能識別的消息, 在Person類中沒有+開頭的demo方法
    reason: ‘-[Person test]: unrecognized selector sent to instance 0x100400000’

常見的錯誤有哪些?
1.只有類的聲明,沒有類的實現
2.漏了@end
@interface和@implementation嵌套
4.成員變量沒有寫在括號裏面
5.方法的聲明寫在了大括號裏面
6.成員變量不能在{}中進行初始化、不能被直接拿出去訪問
7.方法不能當做函數一樣調用
8.OC方法只能聲明在@interface和@end之間,只能實現在@implementation和@end之間。也就是說OC方法不能獨立於類存在
9.C函數不屬於類,跟類沒有聯繫,C函數只歸定義函數的文件所有
10.C函數不能訪問OC對象的成員
11.低級錯誤:方法有聲明,但是實現的時候寫成了函數
12.OC可以沒有@interface同樣可以定義一個類

多文件開發

爲什麼要使用多文件?
答:
一個iOS項目可能會有多個人開發,如果多個人同時修改一個文件,那麼就很可能會產生衝突,比如這個增加一個方法,那個人把這方法刪掉了。另外就是當把多個人寫功能合併起來的時候,也非常困難,寫到一個文件中,無法順暢的進行團隊合作

OC中如何進行多文件開發?
答:
在工作中,通常把不同的類放到不同的文件中,每個類的聲明和實現分開
聲明寫在.h頭文件中,
實現寫在相應的.m文件中去,
類名是什麼,文件名就是什麼

使用多文件開發有什麼好處?
答:
顯著提高團隊協作的效率
提高程序的開發速度
提高程序的可維護性
提高代碼的可讀性

面向對象特性

:面向對象三大特性有哪些?
答:繼承性,封裝性,多態性

什麼是封裝?封裝的好處?封裝的規範?
答:
封裝: 屏蔽內部實現的細節, 僅僅對外提供共有的方法/接口
好處: 保證數據的安全性,將變化隔離
規範: 一般情況下不會對外直接暴露成員變量, 都會提供一些共有的方法進行賦值
成員變量都需要封裝起來

爲什麼要進行封裝?
答:一個類把自己的成員變量暴露給外部的時候,那麼該類就失去對該成員變量的管理權,別人可以任意的修改你的成員變量。

geeter-setter方法

什麼是setter方法?sett方法的書寫格式?
答:setter方法就是給成員變量賦值的方法
格式:
(1) setter方法一定是對象方法
(2) 一定沒有返回值
(3) 一定以set開頭, 並且set後面跟上需要設置的成員變量的名稱去掉下劃線, 並且首字母大寫
(4) 一定有參數, 參數類型一定和需要設置的成員變量的類型一致, 並且參數名稱就是成員變量的名稱去掉下劃線

getter方法就是獲取成員變量值的方法
格式:
(1) getter方法一定是對象方法
(2)一定有返回值, 而且返回值一定和獲取的成員變量的類型一致
(3)方法名稱就是獲取的成員變量的名稱去掉下劃線
(4) 一定沒有參數

成員變量以下劃線開頭有什麼好處?
答:
1.用於區分局部變量/全局變量/形參
2.方便程序編碼, 提高編碼效率

解釋一下什麼是隻讀屬性?什麼是隻寫屬性?可讀可寫的屬性?私有屬性?
答:
一個屬性可以只有getter方法, 沒有setter方法, 這種屬性我們稱之爲只讀屬性
一個屬性也可以只有setter方法, 沒有getter方法, 這種屬性我們稱之爲只寫屬性
如果既有setter方法又有getter方法, 那麼這種屬性我們稱之爲可讀可寫的屬性
一個屬性也可以沒有getter和setter, 這種屬性我們稱之爲私有屬性

點語法和self關鍵字

什麼是點語法?點語法的本質?
答:如果給屬性提供了getter和setter方法, 那麼訪問屬性就又多了一種訪問方式 , 點語法.
點語法的本質是調用了一個類的setter和getter方法

如何使用點語法?
答:
點語法是一個編譯器的特性, 會在程序翻譯成二進制的時候將.語法自動轉換爲setter和getter方法
如果點語法在=號的左邊, 那麼編譯器會自動轉換爲setter方法
如果點語法在=號的右邊, 或者沒有等號, 那麼編譯器就會自動轉換爲getter方法

點語法注意事項?
答:點語法一般用於給成員變量賦值, 如果不是給成員變量賦值一般情況下不建議使用, 但是也可以使用

什麼是成員變量?什麼是對象方法?什麼是類方法?
答:
成員變量:
成員變量是一個實例對象的具體狀態特徵,並且這些狀態特徵是可以改變的,如張三的年齡,身高,體重等

對象方法:
一個實例對象的行爲,比如張三具有吃的行爲,張三做出這樣行爲的時候,有可能會影響,自身的某些狀態特徵,比如張三吃可能會增加張三體重和身高。

類方法:
類方法是某個類的行爲,可以直接通過類名調用;如果在類方法中需要使用某些數據,必須通過參數傳入;類方法不能訪問成員變量。

如何使用self?
如果self在對象方法中, 那麼self就代表調用當前對象方法的那個對象
如果self在類方法中, 那麼self就代表調用當前類方法的那個類
總結:
我們只用關注self在哪一個方法中 , 如果在類方法那麼就代表當前類, 如果在對象方法那麼就代表”當前調用該方法的對象”

self有哪些注意事項?
答:
(1)self會自動區分類方法和對象方法, 如果在類方法中使用self調用對象方法, 那麼會直接報錯
(2)不能在對象方法或者類方法中利用self調用當前self所在的方法

self的有哪些使用場景?
答:
可以用於在對象方法之間進行相互調用
可以用於在類方法之間進行相互調用
可以用於區分成員變量和局部變量同名的情況

繼承基本概念

什麼是繼承?什麼是父類?什麼是子類?如何實現繼承?
答:
1)子類獲得父類的特性就是繼承
2)被繼承的這個類我們稱之爲父類/ 超類
3)繼承了某個類的類我們稱之爲子類
4)在聲明子類的時候,在子類名稱後面通過:父類名稱方式來實現繼承
@interface 子類名稱 : 父類名稱

@end類

當B類繼承A類, 那麼B類就擁有A類所有的屬性和方法(類方法/對象方法)

2.什麼叫方法重寫?重寫後是以什麼順序調用方法的?
答:
(1)如果子類中有和父類中同名的方法, 那麼我們稱之爲方法重寫
注意: 繼承中的方法調用順序, 如果自己有就調用自己的, 如果自己沒有就調用父類的
“方法的調用順序, 先自己再父類, 如果父類中沒有再爺爺類, 如果爺爺類再沒有就找爺爺的爸爸類
如果一直找到NSObject類都沒有找到, 那麼就會報錯
reason: ‘-[Iphone signalWithNumber:]: unrecognized selector sent to instance 0x1003043c0’
注意:在繼承中方法可以重寫, 但是屬性(成員變量)不能重寫

3.方法重寫的使用場景?
答:使用場景:當從父類繼承的某個方法不適合子類,可以在子類中重寫父類的這個方法。

4.繼承的條件是什麼?
答:
不要以爲繼承可以提高代碼的複用性, 以後但凡發現多個類當中有重複代碼就抽取一個父類
只要滿足一定的條件我們才能使用繼承
條件: XXXX 是 XXX / 某某某 is a 某某某

5.繼承的優點是什麼?
答:
提高代碼的複用性
可以讓類與類之間產生關係, 正是因爲繼承讓類與類之間產生了關係所以纔有了多態

6.繼承的缺點是什麼?
答:
耦合性太強(依賴性太強)
super關鍵字

什麼是super?
super是個編譯器的指令符號,只是告訴編譯器在執行的時候,去調誰的方法.

怎麼使用super?
答:
super在類方法中, 一定會調用父類的類方法
super在對象方法中, 一定會調用父類的對象方法
可以利用super在任意方法中調用父類中的方法

super使用場景?
答:
子類重寫父類的方法時想保留父類的一些行爲

多態

什麼是多態?程序中是怎麼體現多態的?
答:
多態就是某一類事物的多種形態
在程序中如何表現:
父類指針指向子類對象

多態的條件是什麼?
答:
1)有繼承關係
2)子類重寫父類方法
3)父類指針指向子類對象

多態的優點是什麼?
答:提高了代碼的擴展性,複用性

多態的注意點?
答:如果父類指針指向子類對象, 需要調用子類特有的方法, 必須先強制類型轉換爲子類才能調用

description方法

使用%@了打印一個對象,輸出的是什麼內容?%@的原理是什麼?
答:%@是用來打印對象的, description方法默認返回對象的描述信息(默認實現是返回類名和對象的內存地址).
其實%@的本質是用於打印字符串.
只要利用%@打印某個對象, 系統內部默認就會調用父類的description方法
調用該方法, 該方法會返回一個字符串, 字符串的默認格式 <類的名稱: 對象的地址>

重寫description方法注意點?
答:如果在description方法中利用%@輸出self會造成死循環
建議: 在description方法中儘量不要使用self來獲取成員變量
因爲如果你經常在description方法中使用self, 可能已不小心就寫成了 %@, self

私有變量和私有方法

什麼是私有變量?什麼是私有方法?
答:
實例變量(成員變量)既可以在@interface中定義, 也可以在@implementation中定義
私有變量:
寫在@implementation中的成員變量, 默認就是私有的成員變量, 並且和利用@private修飾的不太一樣, 在@implementation中定義的成員變量在其它類中無法查看, 也無法訪問

私有方法:
在@implementation中定義的私有變量只能在本類中訪問
property和synthesize基本使用

@porperty是一個編譯器指令
在Xocde4.4之前, 可以使用@porperty來代替getter/setter方法的聲明
也就是說我們只需要寫上@porperty就不用寫getter/setter方法的聲明

編譯器只要看到@property,就知道我們要生成某一個屬性的
getter/setter方法的聲明

@propertyde格式?
答:@property 數據類型 變量名;

@synthesize是什麼指令?作用是什麼?
答:
synthesize是一個編譯器指令, 它可以簡化我們getter/setter方法的實現

@synthesize age = _age; 在給age賦值時,編譯器做了哪些事?
@synthesize age = _age;
(1)在@synthesize後面的age,告訴編譯器, 需要實現哪個@property生成的聲明
(2)告訴@synthesize, 需要將傳入的值賦值給誰和返回誰的值給調用者
如果在@synthesize後面沒有告訴系統將傳入的值賦值給誰, 系統默認會賦值給和@synthesize後面寫得名稱相同的成員變量
@synthesize age;

property增強做了哪些事?
答:
(1)從Xcode4.4以後,對@property進行了增強, 以後只要利用一個@property就可以同時生成setter/getter方法的聲明和實現

(2)如果沒有告訴@property要將傳入的參數賦值給誰, 默認@property會將傳入的屬性賦值給_開頭的成員變量

7.@property的使用場景?
答:
如果不想對傳入的數據進行過濾, 僅僅是提供方法給外界操作成員變量, 那麼就可以使用@property,並且系統會自動給我們生成一個_開頭的成員變量

8.使用property增強後,什麼時候要重寫getter/setter方法?
答:使用property增強,只會生成最簡單的getter/setter方法的聲明和實現, 並不會對傳入的數據進行過濾
如果想對傳入的數據進行過濾, 那麼我們就必須重寫getter/setter方法

9.重寫getter/setter方法有哪些注意點?
答:
如果重寫了setter方法, 那麼property就只會生成getter方法
如果重寫了getter方法, 那麼property就只會生成setter方法
如果同時重寫了getter/setter方法, 那麼property就不會自動幫我們生成私有的成員變量
property修飾符

增強@property使用修飾符後的的格式是什麼?
答:
格式:
@property(屬性修飾符) 數據類型 變量名稱;

@property 有哪些修飾符?各有什麼作用?
答:readwrite: 代表既生成getter方法 , 也生成setter方法
默認情況下 @property就是readwrite的
@property(readwrite) int age;
‘readonly: 代表只生成getter方法不生成setter方法’
可以給setter方法起別名@property(setter=tiZhong:) double weight;
可以給getter方法起別名@property(getter=isMarried) BOOL married;

靜態數據類型和動態數據類型

靜態數據類型的特點:
在編譯時就知道變量的類型,
知道變量中有哪些屬性和方法
在編譯的時候就可以訪問這些屬性和方法,
並且如果是通過靜態數據類型定義變量, 如果訪問了不屬於靜態數據類型的屬性和方法, 那麼編譯器就會報錯

動態數據類型的特點:
在編譯的時候編譯器並不知道變量的真實類型, 只有在運行的時候才知道它的真實類型
並且如果通過動態數據類型定義變量, 如果訪問了不屬於動態數據類型的屬性和方法, 編譯器不會報錯

id和NSObject * 的區別?
答:
NSObject *是一個靜態數據類型
id 是一個動態數據類型

動態數據類型的應用場景?
答:動態類型主要用在多態, 可以減少代碼量, 避免調用子類特有的方法需要強制類型轉換

動態數據類型的弊端是什麼?
答:由於動態數據類型可以調用任意方法, 所以有可能調用到不屬於自己的方法, 而編譯時又不會報錯, 所以可能導致運行時的錯誤

判斷數據類型的有哪些方法?(變量 修改爲 對象)
答:爲了避免動態數據類型引發的運行時的錯誤, 一般情況下如果使用動態數據類型保存一個對象, 在調用這個變量的方法之前會進行一次判斷, 判斷當前對象是否能夠調用這個方法

構造方法

什麼是構造方法?
答:
在OC中init開頭的方法, 我們稱之爲構造方法

構造方法的用途?
答:
構造方法的用途: 用於初始化一個對象, 讓某個對象一創建出來就擁有某些屬性和值

如何實現構造方法?
答:
重寫init方法, 在init方法中初始化成員變量

如何重寫init方法?
答:重寫init方法必須按照蘋果規定的格式重寫, 如果不按照規定會引發一些未知的錯誤
(1)必須先初始化父類, 再初始化子類
(2)必須判斷父類是否初始化成功, 只有父類初始化成功才能繼續初始化子類
(3)返回當前對象的地址
  • (instancetype)init
    {
    // 初始化父類
    // 只要父類初始化成功 , 就會返回對應的地址, 如果初始化失敗, 就會返回nil
    // nil == 0 == 假 == 沒有初始化成功
    self = [super init];
    // 判斷父類是否初始化成功
    if (self != nil) {
    // 初始化子類
    // 設置屬性的值
    _age = 6;
    }
    // 返回地址
    return self;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

自定義構造方法

什麼是自定義構造方法?爲什麼要自定義構造方法?
(1)自定義構造方法就是自定義一個init方法
(2)有時候我們需要在創建某個對象的時候,讓對象的某些屬性就具有值,這時候就需要傳入一些參數給對象的屬性,爲了滿足這個需求,就需要自定義構造方法

自定義構造方法的格式?
答:
(1)一定是對象方法
(2)一定返回id/instancetype
(3)方法名稱一定以init開頭
-(instancetype)initWithAge:(int)age;

自定義構造方法在繼承中有一個原則?
答:自己的事情自己做,屬於誰的屬性就由誰來進行操作
父類的屬性交給父類的方法來處理,子類的方法處理子類自己獨有的屬性

自定義構造方法在子類,如何調用的父類構造方法的?
答:子類在重寫自定構造方法時,一般使用super 調用父類的構造方法,先讓父類將父類的屬性進行初始化
  • (instancetype)initWithAge:(int)age andName:(NSString *)name andNo:(int)no
    {
    if (self = [super initWithAge:age andName:name]) {
    _no = no;
    }
    return self;
    }

    1
    2
    3
    4
    5
    6
    7

instancetype和id區別

instancetype和id區別?
答:
(1)id在編譯的時候不能判斷對象的真實類型
instancetype在編譯的時候可以判斷對象的真實類型

(2)如果init方法的返回值是instancetype, 那麼將返回值賦值給一個其它的對象會報一個警告
如果是在以前, init的返回值是id, 那麼將init返回的對象地址賦值給其它對象是不會報錯的

(3)id可以用來定義變量, 可以作爲返回值, 可以作爲形參
instancetype只能用於作爲返回值

instancetype 應用場景?
答:以後但凡自定義構造方法, 返回值儘量使用instancetype, 不要使用id

類工廠方法

什麼是類工廠方法?
答:用於快速創建對象的類方法, 我們稱之爲類工廠方法

類工廠方法應用場景?
答:類工廠方法中主要用於 給對象分配存儲空間和初始化這塊存儲空間

類工廠方法使用規範?
答:規範:
1.一定是類方法 +
2.方法名稱以類的名稱開頭, 首字母小寫
3.一定有返回值, 返回值是id/instancetype
4.在類工廠方法實現中,調用本類的構造方法,創建實例對象,並返回實例對象

自定義類工廠方法是蘋果的一個規範, 一般情況下, 我們會給一個類提供自定義構造方法和自定義類工廠方法用於創建一個對象。

類工廠方法在繼承中的注意點
以後但凡自定義類工廠方法, 在類工廠方法中創建對象一定要使用self來創建,一定不要使用類名來創建。
類的本質及存儲細節

類的本質是什麼?
答:
(1)類其實也是一個對象, 這個對象會在這個類第一次被使用的時候創建
(2)只要有了類對象, 將來就可以通過類對象來創建實例對象
(3)實例對象中有一個isa指針, 指向創建自己的類對象
(4)類對象中保存了當前對象所有的對象方法
(5)當給一個實例對象發送消息的時候, 會根據實例對象中的isa指針去對應的類對象中查找
(6)所有類對象的繼承關係就是元類對象的繼承關係

類的啓動過程

1.load方法
“load方法調用時間:”
只要程序啓動就會將所有類的代碼加載到內存中, 放到代碼區
“調用次數”
load方法會在當前類被加載到內存的時候調用, 有且僅會調用一次

2.initialize方法
“initialize方法調用時間:”
噹噹前類第一次被使用的時候就會調用(創建類對象的時候)
“調用次數”

SEL類型

SEL是什麼類型?
答:
SEL類型代表着方法的簽名,在類對象的方法列表中存儲着該簽名與方法代碼的對應關係

SEL有什麼作用?
答:
(1)SEL類型的第一個作用, 配合對象/類來檢查對象/類中有沒有實現某一個方法
(2)SEL類型的第二個作用, 配合對象/類來調用某一個SEL方法
(3)配合對象將SEL類型作爲方法的形參

哪個方法是用來檢驗對象是否實現了某個方法?
判斷實例是否實現某個對象方法
(BOOL)respondsToSelector: (SEL)selector
判斷類是否實現某個類方法
(BOOL)instancesRespondToSelector:(SEL)aSelector;

哪些方法是用來調用對象中SEL類型對應的方法?
答:
讓對象執行某個方法
  • (id)performSelector:(SEL)aSelector;
  • (id)performSelector:(SEL)aSelector withObject:(id)object;
  • (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

    1
    2
    3

內存管理

什麼是堆?什麼是棧?
答:
棧(操作系統):由操作系統自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧(先進後出);
堆(操作系統):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由系統回收,分配方式類似於鏈表。

什麼是內存管理?
答:
所謂內存管理, 就是對內存進行管理, 涉及的操作有
分配內存 : 比如創建一個對象, 會增加內存佔用
清除內存 : 比如銷燬一個對象, 能減小內存佔用

內存管理的本質是什麼?
答:
OC對象存放於堆裏面
非OC對象一般放在棧裏面(棧內存會被系統自動回收)

MRC內存管理

什麼是引用計數器?
答:每個OC對象都有自己的引用計數器,它是一個整數,表示有多少人正在用這個對象

引用計數器的作用?
答:
(1)當使用alloc、new或者copy創建一個對象時,對象的引用計數器默認就是1
(2)當對象的引用計數器爲0時,對象佔用的內存就會被系統回收
如果對象的計數器不爲0,那麼在整個程序運行過程,它佔用的內存就不可能被回收(除非整個程序已經退出 )

怎麼操作引用計數器?
答:
給對象發送一條retain消息,可以使引用計數器值+1(retain方法返回對象本身)
給對象發送一條release消息, 可以使引用計數器值-1
給對象發送retainCount消息, 可以獲得當前的引用計數器值
需要注意的是: release並不代表銷燬\回收對象, 僅僅是計數器-1

dealloc 方法的作用?
答:對象即將被銷燬時系統會自動給對象發送一條dealloc消息 (因此, 從dealloc方法有沒有被調用,就可以判斷出對象是否被銷燬)

重寫dealloc方法有什麼注意點?
答:重寫dealloc方法, [super dealloc]一定要寫到所有代碼的最後

內存管理的原則?
答:
(1)誰創建誰release :
如果你通過alloc、new、copy或mutableCopy來創建一個對象,那麼你必須調用release或autorelease

(2)誰retain誰release:
只要你調用了retain,就必須調用一次release

(3)總結:
有加就有減,曾經讓對象的計數器+1,就必須在最後讓對象的計數器-1

setter方法的內存管理
實現set方法內存管理有哪幾步?
答:
(1)retain需要使用的對象
(2)release之前的對象
(3)只有傳入的對象和之前的不同才需要release和retain

  • (void)setRoom:(Room *)room
    {
    // 只有房間不同才需用release和retain
    if (_room != room) {
    // 0ffe1 != 0ffe1
    // 2.將以前的房間釋放掉 -1
    [_room release];
    // retain不僅僅會對引用計數器+1, 而且還會返回當前對象
    _room = [room retain];
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

property修飾符
1.readonly: 只會生成getter方法
readwrite: 既會生成getter也會生成setter, 默認什麼都不寫就是readwrite

2.getter: 可以給生成的getter方法起一個名稱
setter: 可以給生成的setter方法起一個名稱

3.retain: 就會自動幫我們生成getter/setter方法內存管理的代碼
assign: 不會幫我們生成set方法內存管理的代碼, 僅僅只會生成普通的getter/setter方法, 默認什麼都不寫就是assign

4.多線程
atomic :性能低(默認)
nonatomic :性能高
在iOS開發中99.99%都是寫nonatomic

property修飾符 有拿幾點需要注意的問題?
答:
1.相同類型的property修飾符不能同時使用
2.不同類型的property修飾符可以多個結合在一起使用, 多個之間用,號隔開
3.iOS開發中只要寫上property, 那麼就立刻寫上nonatomic

什麼是循環retain?
答:
如果A對用要擁有B對象, 而B對應又要擁有A對象, 此時會形成循環retain
解決循環retain的方法,一邊用retain一邊用assign
autorelease 自動釋放池

什麼是自動釋放池?
答:
autorelease是一種支持引用計數的內存管理方式,只要給對象發送一條autorelease消息,會將對象放到一個自動釋放池中,當自動釋放池被銷燬時,會對池子裏面的所有對象做一次release操作

自動釋放池的優點是什麼?
答:
不用再關心對象釋放的時間
不用再關心什麼時候調用release

簡述自動釋放池的原理?
答:
autorelease實際上只是把對release的調用延遲了,對於每一個autorelease,系統只是把該 Object放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有Object會被調用Release。

自動釋放池有哪些注意事項?
答:
(1)在自動釋放池中創建了對象, 一定要調用autorelease,纔會將對象放入自動釋放池中
(2)一個程序中可以創建N個自動釋放池, 並且自動釋放池還可以嵌套
(3)不要再自動釋放池中使用比較消耗內存的對象, 佔用內存比較大的對象
(4)儘量不要再自動釋放池中使用循環, 特別是循環的次數非常多, 並且還非常佔用內存
(5)千萬不要寫多次autorelease
(6)一個alloc/new對應一個autorelease或者release

自動釋放池是以什麼形式存儲的?
答: 如果存在多個自動釋放池的時候, 自動釋放池是以 “棧” 的形式存儲在堆區
棧的特點: 先進後出

ARC內存管理

問題1:ARC的原理是什麼?
答:當ARC開啓時,編譯器將自動在代碼合適的地方插入retain, release和autorelease,而作爲程序猿,完全不需要擔心編譯器會做錯(除非開發者自己錯用ARC了)。

ARC有什麼優點?
答:
1.完全消除了手動管理內存的煩瑣, 讓程序猿更加專注於app的業務
2.基本上能夠避免內存泄露
3.有時還能更加快速,因爲編譯器還可以執行某些優化

ARC的原則是什麼?什麼是強指針?什麼是弱指針?
答:只要還有一個強指針變量指向對象,對象就會保持在內存中
(1)強指針
默認所有指針變量都是強指針
被__strong修飾的指針
(2)弱指針
被__weak修飾的指針

ARC下@property修飾符有哪些?
答:
strong : 用於OC對象, 相當於MRC中的retain
weak : 用於OC對象, 相當於MRC中的assign
assign : 用於基本數據類型, 跟MRC中的assign一樣

ARC中是怎麼對對象進行內存管理的?
答:
(1)ARC下單對象內存管理
(2)ARC下,所有的指針都是強指針
(3)ARC, A對象想擁有B對象, 那麼就需要用一個強指針指向B對象
(4)A對象不用B對象了, 什麼都不需要做, 編譯器會自動幫我們做

ARC怎麼解決循環引用問題?
答:
ARC和MRC一樣, 如果A擁有B, B也擁有A, 那麼必須一方使用弱指針
也就是說 一端用strong ,一端用weak

Category 分類

書寫Category的格式?
答:
// 分類的聲明
@interface ClassName (CategoryName)
NewMethod; //在類別中添加方法
//不允許在類別中添加變量
@end

ClassName: 需要給哪個類擴充方法
CategoryName: 分類的名稱
NewMethod: 擴充的方法

// 分類的實現
@implementation ClassName(CategoryName)

NewMethod
… …
@end

ClassName: 需要給哪個類擴充方法
CategoryName: 分類的名稱
NewMethod: 擴充的方法

Category的作用?
答:
(1)在不改變原來的類內容的基礎上,爲類增加一些方法。
(2)一個龐大的類可以分模塊開發,由多個人來編寫,更有利於團隊合作

分類,原來類或者父類中的方法調用的順序?
答:先調用分類中的方法(最後參與編譯的分類優先),再調用原來類中的方法,最後掉用父類中的方法

Extension 匿名擴展

什麼是類擴展?
答:延展類別又稱爲擴展(Extension),Extension是Category的一個特例

類擴展格式?
答:
類擴展書寫格式
@interface 類名 ()
@end

類擴展的作用是什麼?
答:寫在.m文件中,可以爲某個類擴充一些私有的成員變量和方法

Block

什麼是Block?
答:Block是iOS中一種比較特殊的數據類型,用來保存某一段代碼

Block的作用?
答:Block用來保存某一段代碼, 可以在恰當的時間再取出來調用
功能類似於函數和方法

Block的格式?
答:Block的格式:
返回值類型 (^block變量名)(形參列表) = ^(形參列表) {
};

協議

什麼是協議?
答:其他語言有接口的概念,接口就是一堆方法的聲明沒有實現.
OC中沒有接口的概念,OC中的接口就是協議.
協議Protocol是由一系列的方法聲明組成的

書寫協議的格式?
答:
格式:
@protocol 協議名稱
// 方法聲明列表
@end

一個類怎麼遵循協議?
答:類遵守協議格式:
@interface 類名 : 父類 <協議名稱1, 協議名稱2,…>
@end

注意:
(1)一個類可以遵守1個或多個協議
(2)任何類只要遵守了Protocol,就相當於擁有了Protocol的所有方法聲明

4.協議和繼承有什麼區別?
答:
(1)繼承之後默認就有實現, 而protocol只有聲明沒有實現
(2)相同類型的類可以使用繼承, 但是不同類型的類只能使用protocol
(3)protocol可以用於存儲方法的聲明, 可以將多個類中共同的方法抽取出來, 以後讓這些類遵守協議即可

什麼是基協議?
答:基協議:是基協議,是最根本最基本的協議,其中聲明瞭很多最基本的方法。
注意:建議每個新的協議都要遵守NSObject協議

6.協議有哪些注意事項?
答:
(1)協議只能聲明方法, 不能聲明屬性
(2)父類遵守了某個協議, 那麼子類也會自動遵守這個協議
(3)在OC中一個類可以遵守1個或多個協議
注意: OC中的類只能有一個父類, 也就是說OC只有單繼承
(4)OC中的協議又可以遵守其它協議, 只要一個協議遵守了其它協議, 那麼這個協議中就會自動包含其它協議的聲明

7.協議中控制方法的能否實現的關鍵字是什麼?各有什麼作用?
(1)注意: 如果沒有使用任何關鍵字修飾協議中的方法, 那麼該方法默認就是required的
(2)注意:@required和@optional僅僅使用程序員之間交流, 並不能嚴格的控制某一個遵守該協議的類必須要實現該方法, 因爲即便不是實現也不會報錯, 只會報一個警告
(3)
@required
如果協議中的方法是@required的, 要求遵守協議的類實現@required所修飾的方法,如果沒有實現該方法, 那麼會報一個警告
(4)
@optional
如果協議中的方法是@optional的, 遵守協議的類可選擇實現@optional所修飾的方法,如果沒有實現該方法, 那麼不會報警告
類型限定

什麼是類型限定?
答:類型限定就是限定一個類必須遵守某個協議

類型限定的格式?
答:數據類型<協議名稱> 變量名
@property (nonatomic, strong) Wife *wife;

類型限定有什麼注意點?
答:
(1)類型限定是寫在數據類型的右邊的
(2)雖然在接受某一個對象的時候, 對這個對象進行了類型限定(限定它必須實現某個協議),
但是並不意味着這個對象就真正的實現了該方法. 所以每次在調用對象的協議方法時應該進行一次驗證

if ([self.wife respondsToSelector:@selector(cooking)]) {
[self.wife cooking];
}

1
2
3

代理設計模式

代理模式的應用場景?
(1)當A對象想監聽B對象的一些變化時, 可以使用代理設計模式
(2)當B對象發生一些事情, 想通知A對象的時候, 可以使用代理設計模式
(3)當對象A無法處理某些行爲的時候,想讓對象B幫忙處理(讓對象B成爲對象A的代理對象)

用什麼類型來接收遵守協議的代理對象?
答:使用id類型接收代理對象

簡述一下協議的編寫規範?
答:
(1)一般情況下, 當前協議屬於誰, 我們就將協議定義到誰的頭文件中
(2)協議的名稱一般以它屬於的那個類的類名開頭, 後面跟上protocol或者delegate
(3)協議中的方法名稱一般以協議的名稱protocol之前的作爲開頭
(4)一般情況下協議中的方法會將觸發該協議的對象傳遞出去

5.一般情況下一個類中的代理屬於的名稱叫做 delegate

6.當某一個類要成爲另外一個類的代理的時候,
一般情況下在.h中用@protocol 協議名稱;告訴當前類 這是一個協議.
在.m中用#import真正的導入一個協議的聲明
Foundation

什麼是框架?
答:
衆多功能\API的集合.
框架是由許多類、方法、函數、文檔按照一定的邏輯組織起來的集合,以便使研發程序變得更容易,在OS X下的Mac操作系統中大約有80個框架爲所有程序開發奠定基礎的框架稱爲Foundation 框架

Foundation 框架有什麼作用?
答:
1.Foundation框架是Mac\iOS中其他框架的基礎
2.Foundation框架包含了很多開發中常用的數據類型:結構體,枚舉, 類

什麼是NSString?
答:一個NSString對象就代表一個字符串(文字內容)
一般稱NSString爲字符串類

如何創建NSString對象?有幾種方法創建一個NSString字符串?
答:
(1)通過@”“直接創建
如果通過@”“創建字符串, 那麼會將字符串放到常量區中
如果是字符串常量, 那麼只要內容相同 , 不會重複創建

NSString *str1 = @”james”;

1

(2)通過alloc或者類工廠方法創建
如果是通過alloc或者類工廠方法創建, 那麼會將字符串放到堆區中

NSString *str2 = [[NSString alloc] initWithString:@"james"];
NSString *str3 = [NSString stringWithFormat:@"jack"];

1
2

如何將字符串寫入到文件中?

NSString *str = @”iOS”;
NSString *path2 = @”/Users/james/Desktop/abc.txt”;
BOOL flag = [str writeToFile:path2 atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@”flag = %i”, flag);

1
2
3
4

6.什麼是URL?
答:
(1)URL的全稱是Uniform Resource Locator(統一資源定位符)
(2)URL是互聯網上標準資源的地址
(3)互聯網上的每個資源都有一個唯一的URL,它包含的信息指出資源的位置
(4)根據一個URL就能找到唯一的一個資源

7.寫URL格式?
答: URL = 協議頭://主機地址/路徑

8.如何創建URL
答:
(1)通過alloc 或者類工廠方法創建

NSURL *url = [NSURL URLWithString:@”file:///Users/james/Desktop/str.txt”];
NSURL *url = [[NSURL alloc] initWithString:@”file:///Users/james/Desktop/str.txt”];

1
2

(2)通過文件路徑創建(默認就是file協議的)

NSURL *url = [NSURL fileURLWithPath:@”/Users/james/Desktop/str.txt”];

1

9.如何獲取本地路徑的信息?獲取本地路徑信息的方法有什麼注意點?
答:獲取本地路徑信息–fileURLWithPath
方法一:
(1)字符串保存路徑

NSString *path = @”file://192.168.13.10/Users/james/Desktop/note/ja.txt”;
NSLog(@”url編碼前: %@”, path);

1
2

(2)將路徑中中文轉換爲UTF-8編碼格式

path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@”url編碼後: %@”, path);

1
2

方法二:
(1)字符串保存路徑,如果訪問本機的文件, 可以省略主機地址
NSString *path = @”file:///Users/james/Desktop/note/ja.txt”;
NSLog(@”url編碼前: %@”, path);

(2)將路徑中中文轉換爲UTF-8編碼格式
path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@”url編碼後: %@”, path);
NSURL *url = [NSURL URLWithString:path];

10.獲取本地路徑的信息

NSURL *url = [NSURL fileURLWithPath:@”/Users/james/Desktop/note/ja.txt”];
NSError *error = nil;
NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (error == nil) {
NSLog(@”str = %@”, str);
}else{
NSLog(@”error = %@”, [error localizedDescription]);
}

1
2
3
4
5
6
7
8

注意點:
URLWithString: 方法不支持中文,所以無法成功創建URL,必須先對路徑字符串進行編碼

fileURLWithPath: 方法支持中文,並且省略協議頭,但是隻能獲取本地方法

11.如何獲取網絡路徑的信息?
答:
獲取網絡路徑的信息–URLWithString

NSURL *url = [NSURL URLWithString:@”http://www.baidu.com“];
NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSLog(@”str = %@”, str);

1
2
3

12.如何將信息寫入到指定文件?
答:
方法一:

NSString *str = @”james”;
NSString *path = @”file:///Users/james/Desktop/未命名文件夾/abc.txt”;
path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:path];
[str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];

1
2
3
4
5

方法二:

NSString *str = @”james”;
NSString *path = @”/Users/james/Desktop/未命名文件夾/abc.txt”;
NSURL *url = [NSURL fileURLWithPath:path];
[str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];

1
2
3
4

總結:
1.如果多次往同一個文件中寫入內容,那麼後一次的會覆蓋前一次的 \
2.方法名中沒有file,路徑中要添加上file協議頭,如果方法名中有file,路徑中就不需要file協議頭
NSString

如何比較兩個字符串的”內容”是否相同?
答:
BOOL flag = [str1 isEqualToString:str2];
NSLog(@”flag = %i”, flag);

如何比較兩個字符串的”地址”是否相同?
flag = (str1 == str2);
NSLog(@”flag = %i”, flag);

如何比較字符串的大小?
答:使用方法compare:
NSOrderedAscending 前面的小於後面的
NSOrderedSame, 兩個字符串相等
NSOrderedDescending 前面的大於後面的

如何忽略大小寫進行比較?
[str1 caseInsensitiveCompare:str2];

如何判斷字符串是否以什麼結尾的?本質是什麼?
答:
本質就是從字符串的最後一個字符開始匹配, 只要不匹配就返回NO

if ([str hasSuffix:@”.gif”]) {
NSLog(@”動態圖片”);
}else{
NSLog(@”不是動態圖片”);
}

1
2
3
4
5

6.如何獲取指定範圍內的字符串?
答:
(1)動態獲取截取的起始位置
NSUInteger location = [str rangeOfString:@”>”].location + 1;
(2)動態獲取截取的長度

NSUInteger length = [str rangeOfString:@”

發佈了23 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章