iOS面試題總結(一)


面試題總結

  • 1、#import 跟#include、@class有什么區別?#import<> 跟 #import”"又什么區別?

    • include和#import都能完整的包含某個文件的內容,#import可以防止一個文件被導入多次。@class只是聲明一個類名,並不會包含包含類的完整聲明,@class可以解決循環包含的問題。
      include通常是用來包含系統自帶的文件,而import則是用來包含自己自定義的文件。

    • import會包含這個類的所有信息,包括實體變量和方法,而@class只是告訴編譯器,其后面聲明的名稱是類的名稱,至於這些類是如何定義的,暫時不用考慮,后面會再告訴你。

    • 在頭文件中, 一般只需要知道被引用的類的名稱就可以了。 不需要知道其內部的實體變量和方法,所以在頭文件中一般使用@class來聲明這個名稱是類的名稱。 而在實現類里面,因為會用到這個引用類的內部的實體變量和方法,所以需要使用#import來包含這個被引用類的頭文件。

    • 在編譯效率方面考慮,如果你有100個頭文件都#import了同一個頭文件,或者這些文件是依次引用的,如A–>B, B–>C, C–>D這樣的引用關系。當最開始的那個頭文件有變化的話,后面所有引用它的類都需要重新編譯,如果你的類有很多的話,這將耗費大量的時間。而是用@class則不會。

    • 如果有循環依賴關系,如:A–>B, B–>A這樣的相互依賴關系,如果使用#import來相互包含,那么就會出現編譯錯誤,如果使用@class在兩個類的頭文件中相互聲明,則不會有編譯錯誤出現。
      所以,一般來說,@class是放在interface中的,只是為了在interface中引用這個類,把這個類作為一個類型來用的。 在實現這個接口的實現類中,如果需要引用這個類的實體變量或者方法之類的,還是需要import在@class中聲明的類進來.

  • 2、屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那種情況下用?

    • readwrite--同時生成get方法及set方法的聲明和實現。

    • readonly--只生成get方法的聲明和實現。

    • assign--set方法的實現是直接賦值,用於基本數據類型。

    • retain--set方法的實現是release舊值,retain新值,用於OC對象。

    • copy--set方法的實現是release舊值,copy新值,用於NSString,Block類型

    • nonatomic--非原子性,set方法的實現不加鎖(atomic主要加的是自旋鎖)

    • unsafe_unretained 用unsafe_unretained聲明的指針,指針指向的對象一旦被釋放,這些指針將成為野指針

  • 3、寫一個setter方法用於完成@property (nonatomic,retain)NSString *name,寫一個setter方法用於完成@property(nonatomic,copy)NSString *name.

     - (void)setName:(NSString *)name
     {
         if (_name != name) {
             //release舊值
             [_name release];
             _name = [name copy];
         }
     }
    
     - (void)setName:(NSString *)name
     {
         if (_name != name) {
             [_name release];
             _name = [name retain];
         }
     }
    
  • 4、對於語句NSString*obj = [[NSData alloc] init]; ,編譯時和運行時obj分別是什么類型?(待補充)

    • 編譯時是NSString類型,執行時是NSData類型。

    • runtime是一個C語言框架,蘋果底層就是這個,

  • 5、常見的object-c的數據類型有那些, 和C的基本數據類型有什么區別?

    • 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。
  • 6、id聲明的變量有什么特性

    • id聲明的對象能指向任何OC對象

    • 用於修飾代理,

    • id相當於NSObject *

  • 7、Objective-C如何對內存管理的,說說你的看法和解決方法?

    • Objective-C內存管理主要有三種方式,MRC(Manual Reference Counting )和ARC(Automatic Reference Counting)、自動釋放池

    • 每個對象都有一個引用計數,當他被alloc init出來時,引用計數為1,然后retain一次加1,release減1,當引用計數為0時,系統就會自動調用delloc方法,在delloc方法中[super delloc]必須寫,這個對象就會被回收。

    • Autorelease-自動釋放池,在iOS運行過程中,會創建無數個池子,這些池子都是以棧型結構存儲的,當一個對象調用autorelease 系統會把該對象放到棧頂的自動釋放池中,當自動釋放池銷毀的時候,系統會對池子中的所有對象進行一次release操作,系統自帶的方法中,如果不包含alloc copy new,那么這些方法的返回對象都是autorelease的,如[NSData data].

    • 自動釋放池的創建方式

      • iOS 5之前

          NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
        
      • iOS 5之后

          		@autoreleasepool
          {//開始代表創建自動釋放池
          ·······
          }//結束代表銷毀自動釋放池
        
    • ARC--只要沒有強指針指向的對象,對象就會被釋放,強指針__strong ,屬性中的strong相當於MRC中的retain,弱指針__weak,屬性中的weak相當於assign,成員變量是弱指針,ARC不允許調用retain release retainCount方法,可以重寫delloc方法,但是不允許調用[super delloc]方法。

  • 8、看下面的程序,三次NSLog會輸出什么?為什么?

      NSMutableArray* ary = [[NSMutableArray array] retain];  
      NSString *str = [NSString stringWithFormat:@"test"];  // 1 
      [str retain];   // 2
      [ary addObject:str]; // 3  
      NSLog(@"%d", [str retainCount]);  
      [str retain];  // 4
      [str release];   // 3
      [str release];   // 2
      NSLog(@"%d", [str retainCount]);  
      [ary removeAllObjects]; // 1  
      NSLog(@"%d", [str retainCount]);  
    
    • str的retainCount創建+1,retain+1,加入數組自動+1
      3
    • retain+1,release-1,release-1
      2
    • 數組刪除所有對象,所有數組內的對象自動-1
      1
  • 9、內存管理的幾條原則時什么?按照默認法則.那些關鍵字生成的對象
    需要手動釋放?在和property結合的時候怎樣有效的避免內存泄露?

    • 誰申請,誰釋放
    • 遵循Cocoa Touch的使用原則;
    • 內存管理主要要避免“過早釋放”和“內存泄漏”,對於“過早釋放”需要注意@property設置特性時,一定要用對特性關鍵字,對於“內存泄漏”,一定要申請了要負責釋放,要細心。
    • 關鍵字alloc 或new 生成的對象需要手動釋放;
    • 設置正確的property屬性,對於retain需要在合適的地方釋放,
  • 10、Object C中創建線程的方法是什么?如果在主線程中執行代碼,方法是什么?如果想延時執行代碼、方法又是什么?

    • 線程創建有三種方法:使用NSThread創建、使用GCD的dispatch、使用子類化的NSOperation,然后將其加入NSOperationQueue;

    • 在主線程執行代碼,方法是performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone:

  • 11、ViewController的didReceiveMemoryWarning怎么被調用?

    • [supper didReceiveMemoryWarning];
  • 12、什么時候用delegate,什么時候用Notification?

    • Delegate是一種點對點的消息傳送機制。傳遞給自己或者其他對象。有時候他還會返回一個影響事件如何被處理的值。
      在內存管理環境中,delegate是弱引用。在垃圾回收環境中,delegate是強引用。

    • Notification是一種一對多的消息傳遞方式。他的實質是廣播信息給所有observer。消息發送者不需要知道誰是消息的接收者。
      他減少了對象之間的依賴。

  • 13、深拷貝和淺拷貝

    淺拷貝

      	//創建一個可變的數組
          NSMutableArray *array = [NSMutableArray array];
          //創建兩個person對象,然后把他們加入到數組中
          Person *p1 = [[Person alloc]init];
          
          p1.name = @"小玉";
          
          Person *p2 = [[Person alloc]init];
          
          p2.name = @"小小玉";
          
          [array addObject:p1];
          
          [array addObject:p2];
          
          
          //淺拷貝
          NSArray *newArray = [array copy];
          
          Person *p = newArray[0];
          
          p.name = @"小王八";
          //輸出array[0]和newArray[0],結果發現他兩輸出都為小王八,
          NSLog(@"array = %@ newArray = %@",((Person *)array[0]).name,((Person *)newArray[0]).name);
    

    深拷貝

      //創建一個可變的數組
      NSMutableArray *array = [NSMutableArray array];
      //創建兩個person對象,然后把他們加入到數組中
      Person *p1 = [[Person alloc]init];
      
      p1.name = @"小玉";
      
      Person *p2 = [[Person alloc]init];
      
      p2.name = @"小小玉";
      
      [array addObject:p1];
      
      [array addObject:p2];
      
    
      NSMutableArray *newArray = [NSMutableArray array];
      
      for (Person *p in array) {
          
          Person *p2 = [[Person alloc]init];
          
          p2.name = p.name;
          
          [newArray addObject:p2];
      }
      
      Person *person = newArray[0];
      
      person.name = @"小王八";
      //輸出為小王八
      NSLog(@"%@",((Person *)newArray[0]).name);
      //輸出為小玉
      NSLog(@"%@",((Person *)array[0]).name);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM