在Objective-C中,任何類的定義都是對象。類和類的實例(對象)沒有任何本質上的區別。任何對象都有 isa
指針。面試
isa
是一個Class 類型的指針。 每一個實例對象有個 isa
的指針,他指向對象的類,而Class裏也有個 isa
的指針, 指向 meteClass
(元類)。元類保存了類方法的列表。當類方法被調用時,先會從自己查找類方法的實現,若是沒有,元類會向他父類查找該方法。同時注意的是:元類也是類,它也是對象。元類也有 isa
指針,它的 isa
指針最終指向的是一個根元類。根元類的 isa
指針指向自己,這樣造成了一個封閉的內循環。數據庫
面試題編程
const int a;
int const a;
const int *a;
int const *a;
int * const a;
int const * const a;
複製代碼
合理地使用關鍵字const可使編譯器保護那些不但願被改變的參數,防止其被無心的代碼修改,減小bug。json
static
變量的做用範圍爲該函數體,不一樣於 auto
變量,該變量的內存只被分配一次,所以其值在下次調用時仍維持上次的值;static
全局變量能夠被模塊內所用函數訪問,但不能被模塊外其它函數訪問;static
函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;static
成員變量屬於整個類所擁有,只會初始化一次,而且在程序退出時纔會回收內存;static
成員函數屬於整個類所擁有,這個函數不接收 this
指針,於是只能訪問類的 static
成員變量。static
用途
volatile
的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都當心地從新讀取這個變量的值,而不是使用保存在寄存器裏的備份。下面是設計模式
self. 是調用 get 方法或者 set 方法 self 是當前自己,是一個指向當前對象的指針 self-> 是直接訪問成員變量數組
懶加載——也稱爲延遲加載,只在用到的時候纔去初始化,好比控制器的view,在第一次用到view時纔會調用loadView方法進行建立,所謂懶加載,寫的是其get方法。我以爲最好也最簡單的一個列子就是tableView中圖片的加載顯示了。一個延時載,避免內存太高,一個異步加載,避免線程堵塞。
注意:若是是懶加載的話則必定要注意先判斷是否已經有了,若是沒有那麼再去進行實例化緩存
你能夠理解 @selector()就是取類方法的編號,他的行爲基本能夠等同C語言的中函數指針,只不過C語言中,能夠把函數名直接賦給一個函數指針,而 Objective-C的類不能直接應用函數指針,這樣只能作一個@selector語法來取.它的結果是一個SEL類型。這個類型本質是類方法的編號 (函數地址)。 方法和選擇器有何不一樣? 答案:selector是一個方法的名字,method是一個組合體,包含了名字和實現。經過一個selector能夠找到方法地址,進而調用一個方法安全
[[NSMutableArray alloc]init]
和 [NSMutableArray array]
bash
[[NSMutableArray alloc]init]
alloc
分配內存,init
初始化,須要手動釋放;[NSMutableArray array]
不須要手動 release
,遵循 autoreleasepool
機制new
與 alloc/init
兩種方式建立對象如今基本上同樣,區別就是使用 new
只能默認 init
進行初始化,alloc
方式可使用其它的 init
開頭的方法進行初始化。網絡
子線程要主動開啓 runloop
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelector:@selector(fireBlock:) withObject:^{
NSLog(@"hello world");
} afterDelay:0.3];
});
複製代碼
上面的代碼片斷原有的目的是異步延遲0.3秒後輸出Hello world。可是運行以後發現不會輸出Hello world。
緣由是:非主線程的NSRunLoop默認沒有開啓,而 - (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
函數內部是經過NSTimer定時器實現,在NSRunLoop沒有開啓的狀況下,NSTimer不會獲得正常運行。
類的加載和初始化
+ (void)load;
+ (void)initialize;
代碼佈局仍是 storyboard ?
對於複雜的、動態生成的界面,建議使用手工編寫界面。
對於須要統一風格的按鈕或UI控件,建議使用手工用代碼來構造。方便以後的修改和複用。
對於須要有繼承或組合關係的 UIView 類或 UIViewController 類,建議用代碼手工編寫界面。
對於那些簡單的、靜態的、非核心功能界面,能夠考慮使用 xib 或 storyboard 來完成。
有些圖片加載的比較慢怎麼處理?你是怎麼優化程序的性能的?
Foundation對象與Core Foundation對象有什麼區別
__bridge_retained
、 __bridge_transfer
__bridge
寫 個「標準」宏,這個宏輸出兩個參數並返回較大的 #define MIN(X,Y) ((X)>(Y)?(Y):(X))
iPhone OS中有沒有垃圾回收? 沒有
self.name=「object」 和 name=「object」有什麼區別?
前者其實是調用了set 方法給變量賦值, 後者是直接給變量賦值
Objective-c中有私有方法嗎?私有變量呢?
沒有私有法,但能夠將方法直接實如今.m文件中不在.h 件中聲明時,外部也不能訪問。
有私有變量
Objective-c中有多重繼承麼?不是的話有聲明替代?
沒有多繼承,能夠經過協議模擬多繼承
多態性
答案:不一樣對象以本身的方式響應相同的消息的能力叫作多態。意思就是假設生物類(life)都用有一個相同的方法-eat;那人類屬於生物,豬也屬於生物,都繼承了life後,實現各自的eat,可是調用是咱們只需調用各自的eat方法。
多態。 主要是將數據類型的肯定由編譯時,推遲到了運行時。好比運行的時候修改某個方法的實現,或者枚舉某個對象都有哪些屬性等等。也就是不一樣的對象以本身的方式響應了相同的消息(響應了eat這個選擇器)。所以也能夠說,運行時機制是多態的基礎。
多態,子類指針能夠賦值給父類。關於多態,繼承和封裝基本最好都有個自我意識的理解。
站在編程的角度來講,就是以C語言的視角看待OC中的對象、類、方法等等 也就是能夠理爲類、對象、方法被映射成了一些結構體、函數、指針等等 好比你要枚舉某個對象有哪些屬性,就能夠調運行時裏的一些函數。 JSonModel、YYModel就是基於運行時實現的,其經過枚舉model裏有哪些屬性、及屬性的類型,去對應的json(數組和字典)來找相應的字段,進而完成解析
obj-c的優缺點
靜態語言:你寫的源代碼編譯以後徹底變成了機器碼 效率高
動態語言:你寫的源代碼沒有徹底編譯成機器碼
全局變量和局部變量在內存中是否有區別?若是有,是什麼區別?
全局變量儲存在靜態數據庫,局部變量在堆棧
id 聲明的變量有什麼特性?
蘋果的安全機制:
寫一個NSString類的實現
+ (id)stringWithCString: (c*****t char*)nullTerminatedCString encoding: (NSStringEncoding)encoding {
NSString *obj;
obj = [self allocWithZone: NSDefaultMallocZone()];
obj = [obj initWithCString: nullTerminatedCString encoding: encoding];
return AUTORELEASE(obj);
}
複製代碼
什麼是平衡二叉樹?
左右子樹都是平衡二叉樹且左右子樹的深度差值的絕對值不大於1
局部變量可否和全局變量重名?
能,局部會屏蔽全局。要用全局變量,須要使用"::"
局部變量能夠與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對於有些編譯器而言,在同一個函數內能夠定義多個同名的局部變量,好比在兩個循環體內都定義一個同名的局部變量,而那個局部變量的做用域就在那個循環體內
如何引用一個已經定義過的全局變量?
答:能夠用引用頭文件的方式,也能夠用extern關鍵字,若是用引用頭文件方式來引用某個在頭文件中聲明的全局變量,假定你將那個變寫錯了,那麼在編譯期間會報錯,若是你用extern方式引用時,假定你犯了一樣的錯誤,那麼在編譯期間不會報錯,而在鏈接期間報錯。
NSString 和 NSMutableString 有什麼區別:
NSString 至關於一個 const char* 不能夠改變。
NSMutableString 至關於 char* 能夠改變內部的內容。
圖片操做:
imageNamed: 優勢是當加載時會緩存圖片。圖片使用頻繁的使用比較好,通常用於加載小圖片。
iamgeWithContentsFile: 大圖片。每次調用,會佔緩存。
imageWithContentsOfFile:僅加載圖片,圖像數據不會緩存。所以對於較大的圖片以及使用狀況較少時,那就能夠用該方法,下降內存消耗。
類實例(成員)變量的 @protected
, @private
, @public
聲明各有什麼含義?
@protected
:受保護的,該實例變量只能在該類和其子類內訪問,其餘類內不能訪問。
@private
:私有的,該實例變量只能在該類內訪問,其餘類內不能訪問。
@public
:共有的,該實例變量誰均可以訪問。
@dynamic 和 @synthesize
@dynamic: 的意思是告訴編譯器,屬性的獲取與賦值方法由用戶本身實現, 不自動生成。對於只讀屬性須要提供 setter,對於讀寫屬性須要提供 setter 和 getter。
@synthesize: 意思是,除非開發人員已經作了,不然由編譯器生成 getter 和 setter 屬性聲明。
UIscrollVew 到了什麼設計模式?還能再foundation庫中找到相似的嗎?
組合模式(composition):全部的container view都用了這個模式
觀察者模式(observer):全部的UIResponder都用了這個模式。
模板模式(Template):全部datasource和delegate接口都是模板模式的典型應用
_btn.frame.origin.y = 10
錯誤
緣由:OC語法規定不容許直接修改某個對象的結構體屬性的成員。_btn 是個對象,frame是個結構體。
對象和結構體是不同的,結構體是C語言中的,裏面能夠定義許多屬性,可是不能定義方法,而對象是便可以定義屬性又能夠定義方法的,是典型的面向對象語法。
如何改變對象中結構體屬性的成員:
// 先取出結構體
CGRect frame = _btn.frame;
// 修改結構體
frame.origin.y -= 10;
// 將修改後的結構體從新賦值回去
_btn.frame = frame;
複製代碼
或者
// 先取出y值
CGFloat y = _btn.frame.origin.y;
// 修改y值
y -= 10;
// 從新設置_btn的y值,其餘屬性和_btn保持不變
_btn.frame = CGRectMake(_btn.frame.origin.x, y, _btn.frame.size.width, _btn.frame.size.height);
複製代碼
若是想讓同一個控件同時即改變位置的移動,又放大。這樣設置是無效果的。這樣操做是建立新的transform而後賦值,給按鈕的transform,第二次賦值的會把以前賦值的給覆蓋,因此會達不到想要的效果。
_btn.transform = CGAffineTransformMakeTranslation(0, 100);
_btn.transform = CGAffineTransformMakeScale(1.2, 1.2);
複製代碼
解決方法:
_btn.transform = CGAffineTransformMakeTranslation(0, 100);
// 在以前的transform狀況下,繼續添加縮放的形變。
_btn.transform = CGAffineTransformScale(_btn.transform, 1.2, 1.2);
複製代碼
四捨五入問題
float i = 1.7;
// 會自動四捨五入,不保留小數
NSLog(@"%0.f",i); // 打印結果2
// 強轉類型不會四捨五入
int j = (int)i;
NSLog(@"%d",j); // 打印結果1
複製代碼
id、nil表明什麼?
常見的object-c的數據類型有那些,和C的基本數據類型有什麼區別?如:NSInteger和int 答:object-c的數據類型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,這些都是class,建立後即是對象,而C語言的基本數據類型int,只是必定字節的內存空間,用於存放數值;NSInteger是基本數據類型,並非NSNumber的子類,固然也不是NSObject的子類。NSInteger是基本數據類型Int或者Long的別名(NSInteger的定義typedef long NSInteger),它的區別在於,NSInteger會根據系統是32位仍是64位來決定是自己是int仍是Long。