Objective-c学习笔记-基础版

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

 

 

 

 

 

 

 ---------------------------   2012 年 8 月 13 日更新 -------------------------------------------

 

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

 

 

 

    

    

  

 

 

 

 

      

         

 

 

 

 

 

 

 

 

posted @ 2012-08-12 17:42  Green.Face.  阅读(3309)  评论(0编辑  收藏  举报