objc學習筆記-基礎

1. xcode 4.3.3以後 NSAutoreleasePool 的用法發生改變,由

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

           ….

   [pool drain];

變爲:

      @autoreleasepool {

       ….

   }

2. 在objc中也存在static 關鍵字,作用與Java中的static 相同即, 內存中只有一份。For example:

    類Maths_,  其中有一個屬性是 static int number(初始化爲 0 ), 類方法使number++,然後new了10個Maths_類, 每個類都調用類方法使number++,看最後結果。

   正常,每個類的number屬性是獨立的,若加上static 因爲內存中只有一份,所以10個類操作的都是同一個number.

3. self 關鍵字作用同Java中的this相同,即誰調用誰就是self/this.

4. 在方法中如果用了new/[~ alloc]分配內存,就要在方法的結尾手動的釋(release)內存.

5. objc中的繼承我個人稱之爲向上繼承,即,子類可以向上繼承所有父類,父類的父類的屬性和方法。

6. @class A和#import "A.h"兩種方法注入類時 ,有什麼區別?

    答:@class只是告訴當前類, A是一個類,並不用處理。(效率高,因爲只注入類名)

           #import "A.h" 是把整個A類注入到當前類中。(相對是@class效率低,因爲把整個類注入)

     那麼什麼時候用@class A ,什麼時候用#import "A.h"呢?

     答:當前類沒有調用任何A類的方法和屬性的時候,無需用#import.

            繼承的時候,必須用#import

7. 如何在當前類中,釋放繼承的類所佔的內存:

   答: 重寫dealloc方法

          - (void) dealloc {

       [super dealloc];

       // [~ release];

       ...

      }

          

8. objc特徵 :多態,動態類型和動態綁定

  

    多態:存在繼承關係的幾個類,在定義的時候,都用到根類的名字,不過在運行時,會根據具體的類型,調用不同子類的方法。

   動態類型:id 可以接受任何的數據類型,缺點就是容易發生運行時異常。

          id定義的時候,不用加星號。 id a = b;

          運行階段,才能確定的類型。

   動態綁定:程序運行過程中,一些id類型的類,會根據實際情況,進行響應的類分配。

          運行階段,才能確定調用的方法。

9. 如何定義一個objc的字符串?

   基本上objc的東西都帶ns前綴。

   NSString *str = @"hello world!"

10. 處理動態類型的一些方法有哪些?

   首先要知道獲得類實例(class-object)的方法,例如class a , [a class];

   

   下面是一些方法:

   (1) 對象是不是class-object或其子類的成員- ( BOOL) isKindOfClass: class-object

   (2) 對象是不是class-object的成員? - (BOOL) isMemberOfClass: class-object

  (3) 對象是否包含selector所指定的成員? - (BOOL) respondsToSelector: @selector

   (4) 指定的類實例是否包含selector所指定的方法? + (BOOL) instancesRespondToSelector: @selector

   (5) 對象是指定類的子類嗎? + (BOOL) isSubclassOfClass: class-object

  

   (6) 調用selector指定的方法? - (id) performSelector: @selector

   (7) 同6 - (id) performSelector: selector withObject: object

   (8) -(id) performSelector: @selector withObject:object withObject:object

   isKindOfClass and isMemberOfClass的區別?答:isKindOfClass檢測繼承層次中的關係,isMemberOfClass檢測直接成員的關係。

11. objc 中也存在異常處理機制, try..catch…

    

   格式如下:

   @try {

   }

   @catch(NSException *exception) {

  

   }

12. 如何初始化NSArray?

   答:NSArray *arrs = [[NSArray alloc] initWithObjects: @"a", @"b", @"c", nil];

       or

       NSArray *arrs = [NSArray arrayWithObjects:@"a", @"b", nil];

13. 編寫初始化方法的時候,一般都要在首行編寫:

   self = [super init]; // 即調用父類的初始化方法,不一行是init的寫法。

   然後判斷是否初始化成功了:

   if ( self ) {

  

   }

14. objc中也存在作用域修飾關鍵字,不過只有對實例變量的修飾:

   @propected (默認)

       可以被任何子類訪問

   @private

       只能被自己訪問,不能被子類訪問

   @public

       能被其他類或模塊訪問,此修飾之後,還能用->的方式訪問修飾的變量,根C++中相同。

   @package

      @package is similar to internal for .NET. It means the member is accessible only from the framework in which it is defined.

Note: In 32-bit it acts like @public.

  

   舉例寫法:

   @interface Person : NSObject {

  

   @private

       int handNum;

   @propected

       int headNum;

      

   }

   @end

15. objc中定義全局變量的命名規則。

   舉例:int gMoveNumber = 0;

   前面都要加一個 g 代表是全局變量

16. 定義全局變量2中方法。

   (1)在所有類,方法外,直接定義 int gCount;

   (2)在方法裏面,用關鍵字extern修飾。

       - (void) setABC : (int) val {

          // 定義全局變量

          // extern int gCount = 0;  這種寫法是錯誤的 extern定義的變量不能直接賦值

         

          extern int gCount;

         

          gCount = 1;

       }

17. 在objc中,應該儘量少用extern即外部/全局變量,應該用static來代替extern.

   爲什麼要這樣? 因爲外面變量可以被其他任何文件訪問到,而static 可以編寫相應的方法進行訪問,在安全性上比全局變量好。

18. auto關鍵字,這個關鍵字幾乎天天看到,只不過“隱形”了。例如

   int count    < == > auto int count;

   語義就是,進入方法,分配內存,結束方法,釋放內存。

19. 常量的定義關鍵字 const

   const int a = 100;

20. volatile關鍵字的作用。

   與const相反,定義變量是可變的。

   爲什麼要用呢?

   *outPort = 'O' ;

   *outPort = 'N' ;

   正常的情況下,編譯器發現outPort被重複賦值,就會把第一次outPort從編譯器中除去。

   如果定義:

  

       volatile char *outPort;之後,就不會在編譯環境中除去了。這在特殊環境中有作用。

21. 枚舉數據類型 enum 如何定義及作用?

   答:

       定義:

      

       enum month {

          january = 1,

          february,

          march,

          april,

          may,

          june,

          july,

          august,

          september,

          october,

          november,

          december

       };

       作用:

          歸類,把一組有意義的詞語封裝起來。

22. objc中typedef的作用是什麼?

   答:顧名思義: typedef = type(類型) + define(定義)

  爲數據類型,另外指派一個名稱。

       作用是增加了變量定義的可讀性。

       例如:

          typedef int Counter;

         

          Counter num = 0;

  

23. 通常typedef 與enum連用。如下:

   typedef enum {

  

       january = 1,

       february 

   } MONTH;

   // typedef enum { january =1, february } Month;

   這樣與enum Month {…} 有什麼區別呢?

   答: 這樣 在定義變量的時候就不用enum了

       Month thisMonth = february;

       enum Month thisMonth = february;

24. 擴展新類方法的方式有哪些?

   答:(1)繼承 (2)重載  (3)分類  (4)協議

25. 分類擴展的方式舉例

   #import "Fraction.h"

   @interface Fraction (MathOps)

   - (void) methodA;

   - (void) methodB;

   @end

   @implementation Fraction (MathOps)

   - (void) methodA {

   }

   /*  分類中的方法可以不實現

   - (void) methodB {

   }

   */

   @end

26. 使用分類時的注意事項。

   (1)使用分類時,不能添加實例變量。

   (2) 在分類中定義方法時,注意不能與原類方法重名,不然原方法將被覆蓋。

   (3) 分類中的方法,可以不實現。

27. objc的協議。

   (1)格式:

       @protocol XXX

       - (void) methodX;

       @end

   (2)本質,定義了一系列沒有實現的方法。

   (3)協議的使用

  

       @interface Fraction <XXX  /* , ??? 多個協議用‘,’隔開*/>

       @end

      

       @implementation Fraction

      

       // XXX中的方法不是必須實現的,如果沒有實現,xcode會產生警告

       - (void) methodX {

          NSLog(@"implement the method which in @protocol XXX");

       }

      

      

       @end

28. 父子類協議示意圖

   父 ----<遵守協議a>

   |            |

   |            |

                  |

   子  <-----

29. 問,我用了一個自己寫的協議XY, 但是我沒有實現協議中的方法,這樣編譯器就會給我發一則警告,如何讓它不警告。

   代碼如下:(協議應該定義在單獨的文件中)

   @protocol XY

   - (void) xyMethod;

   @end

   /////////////////////

   @interface Fraction <XY>

   @end

   @implementation Fraction

  

   // 不實現xyMethod方法

   @end

   ==== 若修改代碼 ====

  

   @protocol XY

   @optional

   - (void) xyMethod;  

   @end

   加上@optional關鍵字 就不會產生警告了。

30. 如何檢查一個對象是否遵循某項協議

   - (BOOL) conformsToProtocol: 方法

   例如:[currentObject conformsToProtocol: @protocol (Drawing)]

31. 什麼是合成對象?

   一個類包含其他類的一個或多個對象。 這個類實例化出來的對象就叫做合成對象。

   例如:

   @interface Square : NSObject {

       Rectangle *rect;

   }

   @end

32. 簡單說說預處理程序?

   & 幾點理解:

       (1)定義‘特殊常量’

       (2)定義表達式和任何東西

       (3)類似於程序中的全局文本替換

   & 定義預定義名稱的時候,一種寫法是全都用大寫,另一個是名稱前面加k,例如:

       #define TURE 1              #define kTure 1

   &#define 語句的基本用途之一就是給符號名稱指派程序常量,例如:

  

       #define TURE 1

   & 定義表達式,例如:

       #define       TWO_PI       2.0 * 3.141592653

   & 爲什麼預定義後面不能寫';'?

      

       答:因爲預定義的本質是文本替換,如果最後加上了分號,分號也將被替換到程序中。例如:

          #define PI   3.1415926 ;

      

           return PI * r;    == >   return 3.1415926; * r;

   & 看如下預定義是否正確,若錯誤,錯在哪裏?

       #define IS_LEAP_YEAR year % 4 == 0 && year % 100 != 0

                           || year % 400 == 0

       答:錯誤,預定時語句,如果過長,寫在兩行時,第一行的結尾處要添加 ‘\’告知編譯器還有後續

       內容。 修改如下:

       #define IS_LEAP_YEAR    year % 4 == 0 && year % 100 != 0 \

                           || year % 400 == 0

   & 預定義語句可以帶參數,如下:

  

       #define IS_LEAP_YEAR(y)        y % 4 == 0 && y % 100 !=0 \

                               || y % 400 == 0

    *** 注意,這種寫法有陷阱存在,正在下面有提到.  正確的寫法是 #define IS_LEAP_YEAR(y) (y)%4 ==0 && (y)%100 != 0 || (y) %400 ==0

       使用預定義的時候,寫法如下:

       int year = 2012;

       if (IS_LEAP_YEAR(year)) {

          NSLog(@"2012 year is leap year! ");

       }

       這裏有一點需要注意:帶有參數的預定義,預定義名稱與參數列表的左半邊括號不能有空格。例如:

      

       #define IS_LEAP_YEAR (y) ..   就是錯誤的寫法。爲什麼呢??

       答:因爲預定義時文本替換,如果有空格,就會把 IS_LEAP_YEAR替換成 “(y)   y % 4 == 0 && y %

       100 !=0 \ || y % 400 == 0 ”

   & 預定義也叫宏定義,宏定義存在一個‘陷阱’, 如下:

      

       #define kSquare(x)   x * x

       int v = 100;    

       return kSquare(v + 1);

       這裏,通常人們會認爲kSquare(v + 1) 得到的結果時 (v + 1) * (v + 1),可時宏定義時文本替換,所以

       看替換的結果,

          x * x == > v + 1 * v + 1 ;

       解決辦法:

          #define    kSquare(x)   ( (x) * (x))

          這樣替換的結果爲 ((v + 1) * (v + 1))

   & 定義一個宏,判斷某字母是否是小寫字母?

   答:

       #define   IS_LOWER_CASE(x)     (  ( (x) > 'a' ) && ( (x) < 'z')  )

   & 定義一個預定義,把小寫字母轉換成大寫字母?

   答:

       #define   TO_UPPER(x)      (   IS_LOWER_CASE(x) ? ((x) - 'a' + 'A')  : (x)  )

  

   & 宏定義中的 #

       若果在定義宏的時候,在參數前放置# ,則結果不是替換,是把宏參數轉成c風格的字符串。如下:

       #define str(s) #s

       str(testing);的結果爲: "testing"

       另一個例子:

      

       #define     printInt(var)    printf(#var " = %i\n", var)     

  

       int count = 100;

       printInt(count) == > printf("count" "= %i\n", count);

  

   & 宏定義中的 ##

  

       答:##在宏定義中是連接符作用。如下:

          #define printf(n)    printf(x ## n )

          int n = 100;

          printf(n) == > printf(x100)

      

33. 簡單說說條件編譯?

   & objc中預處理程序提供了一項名爲條件編譯(conditional compilation)的功能。

   & 條件編譯的用途是什麼?

       條件編譯通常用於創建可以在不同計算機系統上編譯運行的程序。它還經常用來開關程序中的各種語 

   句,例如:用來輸出變量值或跟蹤程序執行流程的調試語句。

   & 條件編譯的關鍵子有哪些?

  

       答:#ifdef , #endif, #else , #elif , #ifndef.  舉例如下:

       #ifdef MAC_OS_X

       #  define DATADIR  "/uxn1/data"

       #else

       #  define DATADIR   "\usr\data"

       #endif

   & 在程序中,如何應用呢?

       答:[預留]

34. 什麼是框架, 及其作用?舉幾個常用的框架。

   答:框架是由許多類,方法,函數,文檔按照一定的邏輯組織起來的集合。以便使研發程序變得更容易。

       — Foundation框架是基礎框架,主要是允許用一些基礎對象,如數字和字符串。還允許使用對象集合    如,數組,字典和集合,還由一些日期處理,自動化內存管理,文件系統等

       — Application Kit 框架:用來開發交互式圖形應用程序。

       Cocoa = Foundation + Application Kit

       Cocoa Touch = Foundation + UIKit

35. Foundation框架提供的基礎對象是什麼?

   答:數字,字符串, 集合。

       集合包括:數組, 字典, 集。

36. NSNumber 是對象,還是typedef? 它可以封裝哪些基礎類型?

   答:NSNumber 是對象,他可以封裝int float double BOOL char long. 他們的初始化方法都是對應的。

       [NSNumber numberWith…];

      

       例如:int類型就是NSNumber *myInt = [NSNumber numberWithInteger: 100];

37. Xcode 4.3.3 以後的release爲何不可用了??

   答:Xcode4 ARC(Automatic Reference Counting)有所變動,Xcode4.3自動在compile time處理release,也就是,你寫alloc,compiler自動在code gen時加入相對的release,這作法是爲了解決iOS仰賴程式設計師(app designer)負責memory management的問題(也就是你alloc後必需自己release這問題)。

不想用ARC的話,在Xcode4.3 File/New/New project及Choose a template for your new project選定template後的Choose options for your new project畫面,"不勾選"UseAutomatic Reference Counting,這樣你就可在你的project中試用alloc/release了。

38.  #define  與  typedef 如何區分?

   答:& define 定義,文本替代。

          #define PI 3.14

       & typedef 類型定義,顧名思義,就重新定義類型的。

          typedef struct _NSRange {

                  NSUInteger location;

                  NSUInteger length;

                     } NSRange;

39. NSLog(@"%2i") 與 NSLog(@"%i") 的區別是什麼?

   答:2i,不足2位的值不是補零,就是補空格

40. NSArray不能存放簡單類型,只能存放對象。

41. C語言本身提供數組與Foundation提供的數組,你用哪個?爲什麼?

   答: C語言本身提供的數組是最底層的數組,雖然操作複雜,但是效率高.

       Foundation提供的數組,操作相對容易,但是效率相對比C語言本身低。

42. 數組的一種快速循環的方法是什麼?

   NSArray *arr = [NSArray arrayWithObjects:@"sdf",@"dfdsa", nil];

      

     for (NSString* temp in arr) {

         NSLog(@"%@", temp);

     }

43. 數組的排序問題,也是面試、工作長問的問題?

   答:

44. 分別說出NSArray 和 NSMutableArray的5個常用方法。

   答:& NSArray :  [NSArray arrayWithObjects: obj1, obj2, obj3…, nil]     

                   

                 [array1 containsObject: obj]

                 [array1 objectAtIndex: i]

                 [array1 count]

                 [array1 indexOfObject: obj];

       & NSMutableArray:   addObject:obj

                        insertObject:index

                        arrayWithCapacity: size

                        replaceObjectAtIndex: i    withObject:obj

                        removeObject: obj

                        removeObjectAtIndex: i

45. 詞典對象,和鍵關聯的值可以是任何對象,但他們不能爲nil.

46. 用for( in ) 遍歷字典的時候,例如:

       NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:

                                          @"HELLO WORLD",@"name" ,

                                          nil];

      

      

        for (NSString *key in dic) {

            NSLog(@"%@",[dic objectForKey:key]);         

        }

   從字典遍歷出來的是key值,然後通過key值,取出value.

48. NSSet 和NSMutableSet裏面如果存放了相同的對象,則會自動刪除重複的。 如果要保持重複的,那麼用NSCountedSet。

49. 兩個集合如何求交集和並集?

    答:& 舉例如下:

      NSMutableSet *set1 = [NSMutableSet setWithObjects:@"1", @"2", @"3", nil];

      NSMutableSet *set2 = [NSMutableSet setWithObjects:@"1", @"4", @"5", nil];

      [set1 unionSet: set2]; 

      NSLog(@"%@", set1);

    & 交集: 可以通過 BOOL flag = [ set1 intersectsSet: set2] ;  判斷是否存在交集. 如果有.  循環倆個Set 進行比較.

50. NSCountedSet的本質?

   答:NSCountedSet 並不是存儲相同對象的兩份,而是由幾個計數器,專門計算每個對象存儲的數量。

countForObject專門計算每個對象的數量。

51. xcode 4.3.3以後的內存管理髮生了什麼改變?例如:[obj retainCount];  [obj retain]; [obj release];都不可

用了。

答: 同標籤 37.

52. 正是協議與非正式協議的區別?

   答:正是協議的方法必須全部實現,非正是協議的方法不必全部實現。

53. 在@interface中,不能直接賦值,如下是錯誤的:

   @interface a : NSObject {

  

       // int a = 100; 

       int a; // 正確的寫法

   }

   @end

 

54. 全局變量  和  extern的使用舉例 ?

  答: 先看例子:

  蒼井空.h 文件:

    #import <Foundation/Foundation.h>

    int gCount;

    @interface 蒼井空 : NSObject

    @end

  孫悟空.m文件中的方法:

  @implement 孫悟空

  

  - (void) use蒼井空 {

    // 這裏要使用 蒼井空.h中的 gCount

    1.要告訴編譯器,我要用一個全局變量.

    extern int gCount;

    2.就可以正常的應用全局變量了

    gCount = 1;

  }

  @end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章