本分享是面向有意向從事iOS開發的夥伴及蘋果產品的發燒友,亦或是已經從事了iOS的開發人員,想進一步提高者。假設您對iOS開發有極高的興趣,可以與我一塊兒探討iOS開發。一塊兒學習,共同進步。假設您是零基礎。建議您先翻閱我以前分享的iOS開發分分鐘搞定C語言系列,而後在開始Objective C語言的學習,假設您遇到問題也可以與我探討。另外將無償分享本身整理出來的大概400G iOS學習視頻及學習資料,都是乾貨哦。可以新浪微博私信➕關注極客James,期待與您的共同窗習和探討!css
!ios
因爲時間有限,天天在工做之餘整理的學習分享,不免有不足之處,也但願各路大神指正!數據庫
本次整理的內容涵蓋Objective C 語言很是多重要問題及細節。很是重要哦!設計模式
made by 極客James
api
OC中主要開發在什麼平臺上的應用程序?數組
答:可以使用OC開發Mac OS X平臺和iOS平臺的應用程序安全
OC中新增關鍵字大部分是以什麼開頭?
答:OC中新增關鍵字大部分是以@開頭ruby
OC中新添加了那些數據類型?
答:Block類型
指針類型(Class, id類型)
空類型
特殊類型(SEL, nil)bash
面向對象特性是什麼?markdown
答:繼承性,封裝性,多態性
答: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.怎樣訪問對象中的屬性?
答:使用指針訪問
格式: 指針名->_屬性名;
方法和函數的差異?
答:
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{
}
類方法和對象方法的差異?
答:
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
爲何要使用多文件?
答:
一個iOS項目可能會有多我的開發,假設多我的同一時候改動一個文件,那麼就很是可能會產生衝突,比方這個添加一個方法,那我的把這方法刪掉了。
另外就是當把多我的寫功能合併起來的時候,也很是困難,寫到一個文件裏,沒法順暢的進行團隊合做
OC中怎樣進行多文件開發?
答:
在工做中,一般把不一樣的類放到不一樣的文件裏,每個類的聲明和實現分開
聲明寫在.h頭文件裏,
實現寫在相應的.m文件裏去,
類名是什麼,文件名稱就是什麼
使用多文件開發有什麼長處?
答:
顯著提升團隊協做的效率
提升程序的開發速度
提升程序的可維護性
提升代碼的可讀性
:面向對象三大特性有哪些?
答:繼承性,封裝性,多態性
什麼是封裝?
封裝的長處?封裝的規範?
答:
封裝: 屏蔽內部實現的細節, 僅僅對外提供共同擁有的方法/接口
長處: 保證數據的安全性,將變化隔離
規範: 普通狀況下不會對外直接暴露成員變量, 都會提供一些共同擁有的方法進行賦值
成員變量都需要封裝起來
爲何要進行封裝?
答:一個類把本身的成員變量暴露給外部的時候,那麼該類就失去對該成員變量的管理權,別人可以隨意的改動你的成員變量。
什麼是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, 這樣的屬性咱們稱之爲私有屬性
什麼是點語法?點語法的本質?
答:假設給屬性提供了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使用場景?
答:
子類重寫父類的方法時想保留父類的一些行爲
什麼是多態?程序中是怎麼體現多態的?
答:
多態就是某一類事物的多種形態
在程序中怎樣表現:
父類指針指向子類對象
多態的條件是什麼?
答:
1)有繼承關係
2)子類重寫父類方法
3)父類指針指向子類對象
多態的長處是什麼?
答:提升了代碼的擴展性,複用性
多態的注意點?
答:假設父類指針指向子類對象, 需要調用子類特有的方法, 必須先強制類型轉換爲子類才幹調用
使用%@了打印一個對象,輸出的是什麼內容?%@的原理是什麼?
答:%@是用來打印對象的, description方法默認返回對象的描寫敘述信息(默認實現是返回類名和對象的內存地址).
事實上%@的本質是用於打印字符串.
僅僅要利用%@打印某個對象, 系統內部默認就會調用父類的description方法
調用該方法, 該方法會返回一個字符串, 字符串的默認格式 <類的名稱: 對象的地址>
重寫description方法注意點?
答:假設在description方法中利用%@輸出self會形成死循環
建議: 在description方法中儘可能不要使用self來獲取成員變量
因爲假設你常常在description方法中使用self, 可能已不當心就寫成了 %@, self
私有方法:
在@implementation中定義的私有變量僅僅能在本類中訪問
@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 有哪些修飾符?各有什麼做用?
答: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)本身定義構造方法就是本身定義一個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;
}
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.load方法
「load方法調用時間:」
僅僅要程序啓動就會將所有類的代碼載入到內存中, 放到代碼區
「調用次數」
load方法會在當前類被載入到內存的時候調用, 有且僅會調用一次
2.initialize方法
「initialize方法調用時間:」
噹噹前類第一次被使用的時候就會調用(建立類對象的時候)
「調用次數」
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;
什麼是堆?什麼是棧?
答:
棧(操做系統):由操做系統本身主動分配釋放,存放函數的參數值。局部變量的值等。其操做方式類似於數據結構中的棧(先進後出)。
堆(操做系統):通常由程序猿分配釋放。若程序猿不釋放。程序結束時可能由系統回收,分配方式類似於鏈表。
什麼是內存管理?
答:
所謂內存管理, 就是對內存進行管理, 涉及的操做有
分配內存 : 比方建立一個對象, 會添加內存佔用
清除內存 : 比方銷燬一個對象, 能減少內存佔用
內存管理的本質是什麼?
答:
OC對象存放於堆裏面
非OC對象通常放在棧裏面(棧內存會被系統本身主動回收)
什麼是引用計數器?
答:每個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];
}
}
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消息,會將對象放到一個本身主動釋放池中,當本身主動釋放池被銷燬時。會對池子裏面的所有對象作一次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
本身主動釋放池是以什麼形式存儲的?
答: 假設存在多個本身主動釋放池的時候, 本身主動釋放池是以 「棧」 的形式存儲在堆區
棧的特色: 先進後出
問題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
ClassName: 需要給哪一個類擴充方法
CategoryName: 分類的名稱
NewMethod: 擴充的方法
// 分類的實現
@implementation ClassName(CategoryName)
NewMethod
… …
@end
ClassName: 需要給哪一個類擴充方法
CategoryName: 分類的名稱
NewMethod: 擴充的方法
Category的做用?
答:
(1)在不改變原來的類內容的基礎上,爲類添加一些方法。
(2)一個龐大的類可以分模塊開發,由多我的來編寫,更有利於團隊合做
分類,原來類或者父類中的方法調用的順序?
答:先調用分類中的方法(最後參與編譯的分類優先),再調用原來類中的方法,最後掉用父類中的方法
什麼是類擴展?
答:延展類別又稱爲擴展(Extension),Extension是Category的一個特例
類擴展格式?
答:
類擴展書寫格式
@interface 類名 ()
@end
類擴展的做用是什麼?
答:寫在.m文件裏,可以爲某個類擴充一些私有的成員變量和方法
什麼是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可以用於存儲方法的聲明, 可以將多個類中共同的方法抽取出來, 之後讓這些類遵照協議就能夠
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)當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真正的導入一個協議的聲明
什麼是框架?
答:
衆多功能\API的集合.
框架是由不少類、方法、函數、文檔依照必定的邏輯組織起來的集合,以便使研發程序變得更easy,在OS X下的Mac操做系統中大約有80個框架爲所有程序開發奠基基礎的框架稱爲Foundation 框架
Foundation 框架有什麼做用?
答:
1.Foundation框架是Mac\iOS中其餘框架的基礎
2.Foundation框架包括了很是多開發中常用的數據類型:結構體,枚舉, 類
什麼是NSString?
答:一個NSString對象就表明一個字符串(文字內容)
通常稱NSString爲字符串類
怎樣建立NSString對象?有幾種方法建立一個NSString字符串?
答:
(1)經過@」「直接建立
假設經過@」「建立字符串, 那麼會將字符串放到常量區中
假設是字符串常量, 那麼僅僅要內容一樣 , 不會反覆建立
NSString *str1 = @"james";
(2)經過alloc或者類工廠方法建立
假設是經過alloc或者類工廠方法建立, 那麼會將字符串放到堆區中
NSString *str2 = [[NSString alloc] initWithString:@"james"];
NSString *str3 = [NSString stringWithFormat:@"jack"];
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);
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"];
(2)經過文件路徑建立(默認就是file協議的)
NSURL *url = [NSURL fileURLWithPath:@"/Users/james/Desktop/str.txt"];
9.怎樣獲取本地路徑的信息?獲取本地路徑信息的方法有什麼注意點?
答:獲取本地路徑信息–fileURLWithPath
方法一:
(1)字符串保存路徑
NSString *path = @"file://192.168.13.10/Users/james/Desktop/note/ja.txt";
NSLog(@"url編碼前: %@", path);
(2)將路徑中中文轉換爲UTF-8編碼格式
path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"url編碼後: %@", path);
方法二:
(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]);
}
注意點:
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);
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];
方法二:
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.方法名中沒有file,路徑中要加入上file協議頭,假設方法名中有file,路徑中就不需要file協議頭
怎樣比較兩個字符串的」內容」是否一樣?
答:
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(@"不是動態圖片");
}
6.怎樣獲取指定範圍內的字符串?
答:
(1)動態獲取截取的起始位置
NSUInteger location = [str rangeOfString:@」>」].location + 1;
(2)動態獲取截取的長度
NSUInteger length = [str rangeOfString:@"</"].location - location;
NSRange range = NSMakeRange(location, length);
NSString *newStr = [str substringWithRange:range];
NSLog(@"str = %@", str);
NSLog(@"newStr = %@", newStr);
7.怎樣替換字符串中的部分字符?
答:
需求: 將&符號替換爲/
NSString *str = @"http:&&www.weibo.iosjames.com&img&james.gif";
..OccurrencesOfString: 要替換誰
// withString: 用誰替換
NSString *newStr = [str stringByReplacingOccurrencesOfString:@"&" withString:@"/"];
NSLog(@"newStr = %@", newStr);
8.怎樣對字符串首位進行處理?
答:
NSString *str = @"HTTP://www.baidu.com/img/james.GIF";
NSCharacterSet *set = [NSCharacterSet uppercaseLetterCharacterSet];
NSString *newStr = [str stringByTrimmingCharactersInSet:set];
NSLog(@"newStr = |%@|", newStr);
9.怎樣給文件路徑加入一個目錄?
答:
本質就是在字符串的末尾加上一個/ 和指定的內容
注意: 假設路徑後面已經有了/, 那麼就不會加入了
假設路徑後面有多個/, 那麼會本身主動刪除多餘的/, 僅僅保留一個
NSString *newStr = [str stringByAppendingPathComponent:@"james"];
NSLog(@"%@", newStr);
10.怎樣獲取路徑中文件的擴展名?
答:
本質就是從字符串的末尾開始查找., 截取第一個.後面的內容
NSString *newStr = [str pathExtension];
NSLog(@"%@", newStr);
11.怎樣刪除路徑中文件的擴展名?
答:
本質就是從字符串的末尾開始查找.,刪除第一個.和.後面的內容
NSString *newStr = [str stringByDeletingPathExtension];
NSLog(@"%@", newStr);
12.怎樣給文件路徑加入一個擴展名?
答:
本質就是在字符串的末尾加上一個.和指定的內容
NSString *newStr = [str stringByAppendingPathExtension:@"jpg"];
NSLog(@"%@", newStr);
13.怎樣將將字符串轉換爲大寫?
答:
NSString *newStr = [str uppercaseString];
NSLog(@"%@", newStr);
14.怎樣將字符串轉換爲小寫?
答:
NSString *newStr2 = [newStr lowercaseString];
NSLog(@"%@", newStr2);
15.怎樣將字符串的首字符轉換爲大寫
答:
NSString *newStr = [str capitalizedString];
NSLog(@"%@", newStr);
NSMutableString和NSString的差異?
答:
(1)NSString是不可變的, 裏面的文字內容是不能進行改動的
(2)NSMutableString是可變的, 裏面的文字內容可以隨時更改
(3)NSMutableString能使用NSString的所有方法
什麼是可變字符串?什麼是不可變字符串?
答:
不可變字符串:指的是字符串在內存中佔用的存儲空間固定,並且存儲的內容不能發生變化
可變字符串:指的是字符串在內存中佔用的存儲空間可以不固定,並且存儲的內容可以被改動
在字符串後面加入一段字符串?
答:
[strM appendString:@"/image"];
NSLog(@"strM = %@", strM);
4.怎樣刪除字符串中的字符?
技巧: 在開發中, 咱們常常利用rangeOfString和deleteCharactersInRange方法配合起來刪除指定的字符串
NSRange range = [strM rangeOfString:@"xx"];
[strM deleteCharactersInRange:range];
NSLog(@"strM = %@", strM);
5.怎樣在某個字符前面插入love這個單詞?
答:
insertString : 需要插入的字符串
atIndex: 從哪裏開始插入
NSRange range = [strM rangeOfString:@"xx"];
[strM insertString:@"love" atIndex:range.location];
NSLog(@"strM = %@", strM);
什麼是NSArray?
答:NSArray是OC中的數組類,開發中建議儘可能使用NSArray替代C語言中的數組
NSArray有哪些使用注意?
答:
(1)僅僅能存放隨意OC對象, 並且是有順序的
(2)不能存儲非OC對象, 比方int\float\double\char\enum\struct等
(3)它是不可變的,一旦初始化完成後,它裏面的內容就永遠是固定的, 不能刪除裏面的元素, 也不能再往裏面加入元素
(4)NSArray使用NSLog()打印,輸出的是小括號的格式。
(5)NSArray中不能存儲nil,因爲NSArray以爲nil是數組的結束(nil是數組元素結束的標記)。nil就是0。0也是基本數據類型,不能存放到NSArray中。
NSArray有哪些常常用法?
答:
- (NSUInteger)count; 獲取集合元素個數 - (id)objectAtIndex:(NSUInteger)index; 得到index位置的元素
- (BOOL)containsObject:(id)anObject; 是否包括某一個元素
- (id)lastObject; 返回最後一個元素
- (id)firstObject; 返回最後一個元素
- (NSUInteger)indexOfObject:(id)anObject; 查找anObject元素在數組中的位置(假設找不到,返回-1)
- (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range; 在range範圍內查找anObject元素在數組中的位置
4.書寫NSArray簡寫形式?
答:
NSArray *arr = [NSArray arrayWithObjects:@"ldda", @"james", @"jjj", nil];
NSArray *arr = @[@"james", @"jasc", @"jjj"];
獲取數組元素的簡寫
NSLog(@"%@", [arr objectAtIndex:0]);
NSLog(@"%@", arr[0]);
5.怎樣使用加強for循環,遍歷NSArray數組?
答:
逐個取出arr中的元素, 將取出的元素賦值給obj
注意: obj的類型可以依據數組中元素的類型來寫, 不必定要寫NSObject
for (NSString *obj in arr) {
NSLog(@」obj = %@」, obj);
}
6.怎樣使用OC數組的迭代器來遍歷數組?
答:
每取出一個元素就會調用一次block
每次調用block都會將當前取出的元素和元素相應的索引傳遞給咱們
obj就是當前取出的元素, idx就是當前元素相應的索引
stop用於控制何時中止遍歷
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx == 1) {
*stop = YES;
}
NSLog(@"obj = %@, idx = %lu", obj, idx);
}];
7.怎樣對數據進行排序?NSArray *arr = @[@10, @20, @5, @7, @15];
NSLog(@」排序前: %@」, arr);意:**
想使用compare方法對數組中的元素進行排序, 那麼數組中的元素必須是Foundation框架中的對象, 也就是說不能是本身定義對象
NSArray *newArr = [arr sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"排序後: %@", newArr);
8.怎樣將數組寫入文件裏?
答:
NSArray *arr = @[@"eee", @"aaa", @"jjj"];
BOOL flag = [arr writeToFile:@"/Users/james/Desktop/abc.plist" atomically:YES];
NSLog(@"flag = %i", flag);
9.將數組寫入文件裏,有什麼注意事項?
答:
注意(1):
假設將一個數組寫入到文件裏以後, 本質是寫入了一個XML文件
在iOS開發中普通狀況下咱們會將XML文件的擴展名保存爲plist
注意(2)
writeToFile僅僅能寫入數組中保存的元素都是Foundation框架中的類建立的對象, 假設保存的是本身定義對象那麼不能寫入
10.怎樣從文件裏讀取數據到NSArray中?
答:
從文件裏讀取一個數組,此方法在字典轉模型中,經常用到
NSArray *newArray = [NSArray arrayWithContentsOfFile:@"/Users/james/Desktop/abc.plist"];
NSLog(@"%@", newArray);
1.什麼是可變數組?
和NSArray有什麼差異?
答:
(1)NSMutableArray是NSArray的子類
(2)NSArray是不可變的,一旦初始化完成後,它裏面的內容就永遠是固定的, 不能刪除裏面的元素, 也不能再往裏面加入元素
(3)NSMutableArray是可變的,隨時可以往裏面加入\更改\刪除元素
2.怎樣建立一個空的數組?建立可變數組有什麼注意點?
NSMutableArray *arrM = [NSMutableArray array];
NSMutableArray *arrM = [[NSMutableArray alloc] init];
注意:
不能經過@[]來建立一個可變數組, 因爲@[]建立出來的是一個不可變的數組
3.怎樣給可變數組添加內容?
答:
方法一:
[arrM addObject:@"james"];
方法二:
將指定數組中的元素都取出來, 放到arrM中 \
並不是將整個數組做爲一個元素加入到arrM中
[arrM addObjectsFromArray:@[@"james", @"jjj"]];
注意:
下面是將整個數組做爲一個元素加入
[arrM addObject:@[@"ss", @"jjj"]];
NSLog(@"%@", arrM);
4.怎樣給可變數組插入內容?
答:
[arrM insertObject:@"xcq" atIndex:1];
NSRange range = NSMakeRange(2, 2);
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:range];
插入一組數據, 指定數組需要插入的位置, 和插入多少個
[arrM insertObjects:@[@」A」, @」B」] atIndexes:set];
5.怎樣刪除可變數組中的內容?
答:
刪除
[arrM removeObjectAtIndex:0]
刪除數組中最後一個元素
[arrM removeLastObject];
刪除index位置的元素
[arrM removeObject:@"A"];
6.怎樣替換可變數組中的內容?
答:
[arrM replaceObjectAtIndex:1 withObject:@"M"];
//簡寫:
arrM[0] = @"ZS";
NSLog(@"%@", arrM);
7.怎樣獲取可變數組中的內容?
答:
NSLog(@"%@", [arrM objectAtIndex:0]);
什麼是字典?
答:OC中的NSDictionary:依據key找到value,字典中存儲的東西都是鍵值對
怎樣建立字典?
答:
方法一:
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"james" forKey:@"name"];
NSString *name = [dict objectForKey:@"name"];
NSLog(@"name = %@", name);
方法二:
注意: key和value 是一一相應
NSDictionary *dict = [NSDictionary dictionaryWithObjects:@[@"james", @"22", @"1.75"] forKeys:@[@"name", @"age", @"height"]];
NSLog(@"%@ %@ %@", [dict objectForKey:@"name"], [dict objectForKey:@"age"], [dict objectForKey:@"height"]);
方法三:簡寫:
NSDictionary *dict = @{key:value};
NSDictionary *dict = @{@"name": @"james"};
NSLog(@"%@", dict[@"name"]);
NSDictionary *dict = @{@"name":@"james", @"age":@"30", @"height":@"1.75"};
NSLog(@"%@ %@ %@", dict[@"name"], dict[@"age"], dict[@"height"]);
3.怎樣對字典進行遍歷?
答:
NSDictionary *dict = @{@"name":@"james", @"age":@"22", @"height":@"1.75"};
//獲取字典中key和value的個數, 在字典中key稱之爲鍵, value稱之爲值
NSLog(@"count = %lu", [dict count]);
方法一:老式for循環寫法
for (int i = 0; i < dict.count; ++i) {
// 獲取字典中所有的key
NSArray *keys = [dict allKeys];
// 取出當前位置相應的key
// NSLog(@"%@", keys[i]);
NSString *key = keys[i];
NSString *value = dict[key];
NSLog(@"key = %@, value = %@", key, value);
}
方法二:加強for循環寫法
怎樣經過forin遍歷字典, 會將所有的key賦值給前面的obj
for (NSString *key in dict) {
NSLog(@"%@", key);
NSString *value = dict[key];
NSLog(@"key = %@, value = %@", key, value);
}
方法三:OC字典的迭代器來遍歷
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"key = %@, value = %@", key, obj);
}];
4.怎樣對字典文件進行讀寫?
答:
(1)將字典數據寫入文件裏
NSDictionary *dict = @{@"name":@"james", @"age":@"22", @"height":@"1.75"};
[dict writeToFile:@"/Users/james/Desktop/info.plist" atomically:YES];
(2)從文件裏讀取字典數據
注意: 字典和數組不一樣, 字典中保存的數據是無序的
NSDictionary *newDict = [NSDictionary dictionaryWithContentsOfFile:@"/Users/james/Desktop/info.plist"];
NSLog(@"%@", newDict);
NSArray *arr = @[@10, @20, @30, @5];
[arr writeToFile:@"/Users/james/Desktop/abc.plist" atomically:YES];
怎樣建立一個空的可變字典?
答:
NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
怎樣給可變字典加入鍵值對?
答:
[dictM setObject:@"lnj" forKey:@"name"];
簡寫:
dictM[@"name"] = @"james";
會將傳入字典中所有的鍵值對取出來加入到dictM中
[dictM setValuesForKeysWithDictionary:@{@"age":@"30", @"height":@"1.75"}];
3.怎樣刪除可變字典鍵值對?
答:
[dictM removeObjectForKey:@"name"];
[dictM removeObjectsForKeys:@[@"age", @"height"]];
4.怎樣改動可變字典中的鍵值對?
答:利用setObject方法給同名的key賦值, 那麼新值會覆蓋舊值
[dictM setObject:@"88" forKey:@"age"];
簡寫:
dictM[@"age"] = @"88";
5.使用可變字典有什麼注意事項?
答:
(1)不能使用@{}來建立一個可變的字典
NSMutableDictionary *dictM = @{@」name」:@」james」};//編譯就會報錯
[dictM setObject:@」30」 forKey:@」age」];
(2)
假設是不可變字典, 那麼key不能一樣
假設是不可變字典出現了同名的key, 那麼後面的key相應的值不會被保存
假設是在可變數組中, 後面的會覆蓋前面的
NSDictionary *dict = @{@"name":@"lkl", @"name":@"lll"};
NSLog(@"dict = %@", dict);
NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjects:@[@"lkl", @"lll"] forKeys:@[@"name", @"name"]];
NSLog(@"dict = %@", dictM);
6.NSArray和NSDictionary的差異?
答:
NSArray是有序的,NSDictionary是無序的
NSArray是經過下標訪問元素,NSDictionary是經過key訪問元素
1.NSNumber的應用場景?
答:
NSNumber可以將基本數據類型包裝成對象,這樣就可以間接將基本數據類型存進NSArray\NSDictionary中
2.怎樣將基本數據類型轉換爲對象類型?
答:
int age = 10;
double number= 5.1;
int value = 6;
NSNumber *ageN = [NSNumber numberWithInt:age];
NSNumber *numberN = [NSNumber numberWithDouble:number];
NSNumber *valueN = [NSNumber numberWithInt:value];
NSArray *arr = @[ageN, numberN, valueN];
NSLog(@"arr = %@", arr);
3.怎樣將對象類型轉換爲基本數據類型?
答:
int temp = [ageN intValue];
double temp = [numberN doubleValue];
4.怎樣將基本數據類型轉換對象類型簡寫?有什麼注意點?
答:
注意: 假設傳入的是變量那麼必須在@後面寫上(), 假設傳入的常量, 那麼@後面的()可以省略
NSNumber *temp = @(number);
NSNumber *temp =@10.10;
NSLog(@"%@", temp);
1.NSValue的應用場景?
答:
(1)NSNumber是NSValue的子類, 但NSNumber僅僅能包裝數字類型
(2)NSValue可以包裝隨意值
所以, 可以用NSValue將結構體包裝後,加入NSArray\NSDictionary中
2.怎樣利用NSValue包裝常用的結構體?
答:
CGPoint point = NSMakePoint(10, 20);
NSValue *value = [NSValue valueWithPoint:point];
NSArray *arr = @[value];
NSLog(@"%@", arr);
3.怎樣利用NSValue包裝本身定義的結構體?
答:
typedef struct{
int age;
char *name;
double height;
}Person;
Person p = {30, "lld", 1.75};
1.NSDate的應用場景?
答:NSDate可以用來表示時間, 可以進行一些常見的日期\時間處理
[NSDate date]返回的就是當前0時區的時間
2.怎樣獲取當前時區的時間?
答:
(1) date方法建立的時間對象, 對象中就保存了當前的時間
NSDate *now = [NSDate date];
(2)獲取當前所處的時區
NSTimeZone *zone = [NSTimeZone systemTimeZone];
(3)獲取當前時區和指定時區時間的時間差
NSInteger seconds = [zone secondsFromGMTForDate:now];
// NSLog(@"seconds = %lu", seconds);
(4)計算出當前時區的時間
NSDate *newDate = [now dateByAddingTimeInterval:seconds];
NSLog(@"newDate = %@", newDate);
3.怎樣格式化時間?
答:
NSDate 轉 NSString
(1)建立時間
NSDate *now = [NSDate date];
(2)建立時間格式化
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
(3)指定格式
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
(4)格式化時間
NSString *str = [formatter stringFromDate:now];
NSLog(@"%@", str);
NSString 轉 NSDate
(1)獲取時間
NSString *str = @"2015-08-20 07:05:26 +0000";
2.建立時間格式化
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
注意:
假設是從NSString格式化爲NSDate, 那麼dateFormat的格式, 必須和字符串中的時間格式一致, 不然可能轉換失敗
(3)指定格式
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss Z";
4.格式化日期
NSDate *date = [formatter dateFromString:str];
NSLog(@"%@", date);
1.怎樣獲取當前時間的年月日時分秒?
答:
(1)獲取當前時間
NSDate *now = [NSDate date];
NSLog(@"now = %@", now);
得到NSCalendar 日曆對象
NSCalendar *calendar1 = [NSCalendar currentCalendar];
// 利用日曆類從當前時間對象中獲取 年月日時分秒(單獨獲取出來)
// components: 參數的含義是, 問你需要獲取什麼?
// 普通狀況下假設一個方法接收一個參數, 這個參數是是一個枚舉 , 那麼可以經過|符號, 鏈接多個枚舉值
NSCalendarUnit type = NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay |
NSCalendarUnitHour |
NSCalendarUnitMinute |
NSCalendarUnitSecond;
NSDateComponents *cmps = [calendar1 components:type fromDate:now];
NSLog(@"year = %ld", cmps.year);
NSLog(@"month = %ld", cmps.month);
NSLog(@"day = %ld", cmps.day);
NSLog(@"hour = %ld", cmps.hour);
NSLog(@"minute = %ld", cmps.minute);
NSLog(@"second = %ld", cmps.second);
2.怎樣獲取當前時間和指定時間的時間差?
答:
1.過去的一個時間
NSString *str = @"2015-06-29 07:05:26 +0000";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss Z";
NSDate *date = [formatter dateFromString:str];
2.當前的時間
NSDate *now = [NSDate date];
NSLog(@"date = %@", date);
NSLog(@"now = %@", now);
3.比較兩個時間
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit type = NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay |
NSCalendarUnitHour |
NSCalendarUnitMinute |
NSCalendarUnitSecond;
NSDateComponents *cmps = [calendar components:type fromDate:date toDate:now options:0];
NSLog(@"%ld年%ld月%ld日%ld小時%ld分鐘%ld秒鐘", cmps.year, cmps.month, cmps.day, cmps.hour, cmps.minute, cmps.second);
1.什麼是NSFileManager?
怎樣獲取NSFileManager 對象?
答:
NSFileManager是用來管理文件系統的
它可以用來進行常見的文件\目錄操做
NSFileManager *manager = [NSFileManager defaultManager];
2.怎樣推斷一個文件或者目錄是否存在?
答:
BOOL flag = [manager fileExistsAtPath:@"/Users/james/Desktop/video/01-NSArray.text"];
NSLog(@"flag = %i", flag);
3.怎樣獲取文件或目錄的屬性?
答:
NSDictionary *info = [manager attributesOfItemAtPath:@"/Users/james/Desktop/video/acn.mp4" error:nil];
NSLog(@"info = %@", info);
4.怎樣獲取目錄中所有的文件?
答:
注意:
NSArray *res = [manager contentsOfDirectoryAtPath:@"/Users/xiaomage/Desktop/video" error:nil];
NSLog(@"res = %@", res);
獲取當前目錄下所有的文件, 能獲取子目錄下面的文件
NSArray *res = [manager subpathsAtPath:@"/Users/james/Desktop/video"];
NSArray *res = [manager subpathsOfDirectoryAtPath:@"/Users/james/Desktop/video" error:nil];
NSLog(@"res = %@", res);
5.怎樣建立目錄?
答:
createDirectoryAtPath: 告訴系統目錄需要建立到什麼位置
withIntermediateDirectories: 假設指定的文件裏有一些目錄不存在, 是否本身主動建立不存在的目錄
attributes: 指定建立出來的目錄的屬性
error: 是否建立成功, 假設失敗會給傳入的參數賦值
注意: 該方法僅僅能用於建立目錄, 不能用於建立文件
BOOL flag = [manager createDirectoryAtPath:@"/Users/james/Desktop/abc/llq" withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(@"%i", flag);
6.怎樣建立文件?
createFileAtPath: 指定文件建立出來的位置
contents : 文件裏的內容
attributes: 建立出來的文件的屬性
NSData : 二進制數據
注意: 該方法僅僅能用於建立文件, 不能用於建立目錄
1.使用copy功能的前提是什麼?
答:
copy : 需要遵照NSCopying協議,實現copyWithZone:方法
使用mutableCopy的前提
需要遵照NSMutableCopying協議,實現mutableCopyWithZone:方法
2.怎樣使用copy功能?
答:
一個對象可以調用copy或mutableCopy方法來建立一個副本對象
copy : 建立的是不可變副本(如NSString、NSArray、NSDictionary)
mutableCopy :建立的是可變副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
3.copy基本原則?
答:
改動源對象的屬性和行爲。不會影響副本對象
改動副本對象的屬性和行爲,不會影響源對象
4.爲何經過不可變對象調用了copy方法, 不會生成一個新的對象?
答:
因爲原來的對象是不能改動的, 拷貝出來的對象也是不能改動的
既然兩個都不能改動, 因此永遠不能影響到另一個對象, 那麼已經符合需求
因此: OC爲了對內存進行優化, 就不會生成一個新的對象
1.淺複製(淺拷貝。指針拷貝,shallow copy)
源對象和副本對象是同一個對象
源對象(副本對象)引用計數器+1,至關於作一次retain操做
本質是:沒有產生新的對象
2.深複製(深拷貝,內容拷貝,deep copy)
源對象和副本對象是不一樣的兩個對象
源對象引用計數器不變,副本對象計數器爲1(因爲是新產生的)
本質是:產生了新的對象
1.@property中的copy的做用是什麼?
答:
(1)防止外界改動內部的數據
(2)可以使用copy保存block, 這樣可以保住block中使用的外界對象的命
block默認存儲在棧中, 棧中的block訪問到了外界的對象, 不會對對象進行retain
2.@property內存管理原則?
答:
MRC
1> copy : 僅僅用於NSString\block
2> retain : 除NSString\block之外的OC對象
3> assign :基本數據類型、枚舉、結構體(非OC對象),當2個對象相互引用,一端用retain,一端用assign
ARC
1> copy : 僅僅用於NSString\block
2> strong : 除NSString\block之外的OC對象
3> weak : 當2個對象相互引用,一端用strong,一端用weak
4> assgin : 基本數據類型、枚舉、結構體(非OC對象)
3.怎樣解決block中的循環引用?
答:假設對象中的block又用到了對象本身, 那麼爲了不內存泄露, 應該將對象修飾爲__block
__block Person *p = [[Person alloc] init]; // 1
p.name = @"james";
NSLog(@"retainCount = %lu", [p retainCount]);
p.pBlock = ^{
NSLog(@"name = %@", p.name); // 2
};
NSLog(@"retainCount = %lu", [p retainCount]);
p.pBlock();
1.本身定義類怎樣實現copy操做?
答:
(1)之後想讓本身定義的對象可以被copy僅僅需要遵照NSCopying協議
(2)實現協議中的- (id)copyWithZone:(NSZone *)zone
(3)在- (id)copyWithZone:(NSZone *)zone方法中建立一個副本對象, 而後將當前對象的值賦值給副本對象就能夠
- (id)copyWithZone:(NSZone *)zone
{
// 1.建立一個新的對象
Person *p = [[[self class] allocWithZone:zone] init];
// 2.設置當前對象的內容給新的對象
p.age = _age;
p.name = _name;
// 3.返回新的對象
return p;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// 1.建立一個新的對象
Person *p = [[[self class] allocWithZone:zone] init];
// 2.設置當前對象的內容給新的對象
p.age = _age;
p.name = _name;
// 3.返回新的對象
return p;
}
1.什麼是單例模式?
答:類的對象成爲系統中惟一的實例,提供一個訪問點,供客戶類 共享資源
單例就是無論怎麼建立都僅僅能有一個實例對象
2.什麼狀況下使用單例?
答:
(1)類僅僅能有一個實例,並且必須從一個爲人熟知的訪問點對其進行訪問,比方工廠方法。
(2)這個惟一的實例僅僅能經過子類化進行擴展,並且擴展的對象不會破壞client代碼。
3.建立單例對象的方法通常以什麼開頭?
答:
(1)普通狀況下建立一個單利對象都有一個與之相應的類方法
(2)普通狀況下用於建立單利對象的方法名稱都以share開頭, 或者以default開頭
單例在多線程的應用?
答:多線程中的單例
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
// 下面代碼在多線程中也能保證僅僅執行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone] init];
});
return _instance;
}