您的位置:首页 > 移动开发 > IOS开发

iOS之09-特有语法

2016-05-11 16:41 447 查看
1、分类 - Category

 1> 基本用途

  分类:可以给某个类扩充一些方法(不修改原来的代码)  

  如何在不改变原来类模型的前提下,给类扩充一些方法?

  有2种方式: 继承; 分类(Categoty)。

 2> 格式

  分类的声明

  @interface 类名(分类名称)
   // 方法声明
    @end

  分类的声明

  @implementation 类名(分类名称)
   // 方法声明
    @end

 3> Category在 Xcode 7.2 创建方法

  New File -> Objective-C File -> File为分类名,File Type选Category,class为创建分类的类

  分类名一般以模块名命名





 4> 好处

  当一个类特别庞大,并且具有不同的功能,我们可以一个功能写在一个分类中,更有利于团队开发。

 5> 使用注意

分类只能增加方法,不能增加成员变量

分类方法实现中可以访问原来类中的成员变量

分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用

分类的优先级最高,方法调用时,优先到分类中查找,然后再去原来类中查找,最后再去父类中找

多个Category中如果实现了相同的方法,只有最后一个参与编译的才会有效

查看编译顺序:点击工程名,build phases -> Compiles Sources 

2、类的本质

 1> 类也是个对象

  其实类也是一个对象,是 Class 类型的对象,简称 "类对象"

  Class 类型的定义

   typedef struct objc_class *Class

  类名就代表着类对象,每个类只有一个类对象

 2> +load 和 +initialize

  ① +load

当程序启动的时候会加载所有的类和分类,并调用所有的类和分类的 +load 方法

先加载父类,再加载子类;也就是先调用父类的 +load ,再调用子类的 +load

先加载原始类,再加载分类

不管程序运行过程有没有用这个类,都会调用 +load 方法

  ② +initialize

在第一次使用某个类时(比如创建对象等),就会调用一次 +initialize 方法

一个类只会调用一次 +initialize 方法,先调用父类的,再调用子类的

 3> 获取类对象的2种方式

  Class c = [Person class]; // 类方法

  或者

  Person *p = [Person new];

  Class c2 = [p class]; // 对象方法

 4> 类对象调用类方法  

  Class c = [Person class];

  Person *p2 = [c new];

3、description 方法

 1> -description 方法

  使用NSLog和%@输出某个对象时,会调用对象的 -description 方法

  -description 决定了实例对象的输出结果,默认情况下,结果是:<类名:内存地址>

 2> +description 方法

  使用NSLog和%@输出某个类对象时,会调用对象的+description 方法

  +description决定了类对象的输出结果,默认情况下,结果是:类名

 3> 修改 NSLog 的默认输出

  重写 -description 或者 +description 方法即可

 4> 死循环陷阱

  如果在 -description 方法中使用 NSLog 打印 self

 5> NSLog打印增强

1         Person *p = [[Person alloc] init];
2
3         // 指针变量地址
4         NSLog(@"%p", &p);
5         // 对象的地址
6         NSLog(@"%p", p);
7         // <类名:对象地址>
8         NSLog(@"%@", p);
9         // 输出代码所在行数
10         NSLog(@"%d", __LINE__);
11
12         // 输出源文件的路径
13         // NSLog输出C语言字符串的时候,不能有中文
14 //        NSLog(@"%s", __FILE__);
15         printf("%s\n", __FILE__);
16
17         // 输出当前函数名
18         NSLog(@"%s", __func__);


4、SEL

 1> 方法的存储位置

  每个方法都有一个与之对应的SEL类型的对象

  根据一个SEL对象就可以找到方法的地址,进而调用方法

  SEL类型的定义

   typedef struct objc_selector *SEL;

 2> SEL对象的创建

SEL sel = @selector(test);
SEL s = NSSelectorFromString(@"test"); // NSSelectorFromString将字符串转为SEL类型的数据


 3> SEL对象的其他用法

  将SEL对象转为NSString对象

// 将SEL对象转为NSString对象
NSString *str = NSStringFromSelector(@selector(test));


  间接调用方法(performSelector: SEL)

1         // 间接调用对象p的方法
2         // 不带参数的方法
3         SEL sel = @selector(test2);
4         [p performSelector:@selector(test2)];
5
6         // 带参数的方法
7         [p test3:@"abc"];
8         [p performSelector:@selector(test3:) withObject:@"a456"];


 4> _cmd

  _cmd 代表着当前方法

1 - (void)test2 {
2
3     // _cmd 代表着当前方法
4     NSString *str = NSStringFromSelector(_cmd);
5
6     // 会造成死循环
7 //    [self performSelector:_cmd];
8
9     NSLog(@"test2----%@", str);
10 }


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: