·您现在的位置: 江北区云翼计算机软件开发服务部 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> Objective-C基础核心语法-总结

Objective-C基础核心语法-总结

作者:佚名      IOS开发编辑:admin      更新时间:2022-07-23

一、点语法本质

  • “点语法”本质是“方法调用”
  • 当使用“点语法”时,编译器会自动展开称相应的方法
  • id类型的对象不能用 点语法
1 //方法调用
2 Student *stu = [[Student alloc] init]; 
3 [stu setAge:10]; 
4 int age = [stu age];
5 //-----------------------------我是华丽分割线-----------------------------
6 //点语法 
7 stu.age = 10; 
8 int age = stu.age;

  

 


二、成员变量的作用域

  • @public : 在任何地方都能直接访问对象的成员变量
  • @PRivate : 只能在当前类的对象方法中直接访问 ( @implementation 中默认是 @private )
  • @protected  : 可以在当前类及其字累的对象方法中直接访问 (默认就是 @protected )
  • @package : 只要处在同一个框架中,就能直接访问对象的成员变量
  • @interface 和 @implementation 中不能声明同名的成员变量
  • 没有 @interface ,只有 @implementation ,也可以开发同一个类

 


三、@property 和 @synthesize 、setter 和 getter 及使用细节

  • @property 用在 @interface 中,用来自动生成 setter 和 getter 声明
  • @synthesize 永在 @implementation 中,用来生成 setter 和 getter 实现
  • @synthesize 细节:1> @synthesize age = _age;(setter 和 getter 实现中会访问成员变量 _age,如果成员变量 _age 不存在,就会自动生成一个 @private 的成员变量 _age 
    •       2> @synthesize age;(setter 和 getter 实现中会访问成员变量 age,如果成员变量 age 不存在,就会自动生成一个 @private 的成员变量 age)
    •       3> 若手动实现了 setter 方法,编译器就只会自动生成 getter 方法
  • 自从 Xcode4.4 后,@property 就独揽了 @synthesize 的功能。也就是说,@property 可以同时生成 settergetter声明实现
  • 默认情况下,setter 和 getter 方法中的实现,会访问下划线 _ 开头的成员变量
 1 //--[interface.h]---Xcode4.2之前的语法---------------我是华丽分割线--------
 2 @property int age;                         //@property
 3 //--[interface.h]--------⬆️等价于⬇️--------
 4 - (void)setAge;
 5 - (int)age; 
 6 
 7 //--[implementation.m]-------------------------------我是华丽分割线--------
 8 @synthesize int age = _age;                //@synthesize
 9 //--[implementation.m]---⬆️等价于⬇️--------
10 - (void)setAge {
11     _age = age;
12 }
13 - (int)age {
14     return _age;
15 }
16 //--[implementation.m]-------------------------------我是华丽分割线--------
17 @synthesize int age;                        //@synthesize
18 //--[implementation.m]---⬆️等价于⬇️--------
19 - (void)setAge {
20     _age = age;
21 }
22 - (int)age {
23     return age;
24 }
25 
26 //--[interface.h]---Xcode4.4之后有了以下新语法-------我是华丽分割线-------
27 @property int age;                           //@property
28 //--[interface.h]---------⬆️等价于⬇️-------
29 @interface Student:NSObject{
30     int _age;
31 }
32 - (void)setAge;
33 - (int)age; 
34 //--[implementation.m]---------------------
35 - (void)setAge {
36     _age = age;
37 }
38 - (int)age {
39     return _age;
40 }                 

 


四、id

  • 是万能指针,能指向任何对象,相当于 NSObject * , id 后面不要加上*
  • 调用一个不存在的方法,编译器会马上报错
  • id 是一个结构体,OC 对象本身是一个结构体
1 typedef struct objc_object {
2   Class isa;    //每个对象都有一个isa,且isa始终指向当前类本身
3 } *id;            // id 定义为一个结构指针

 


五、构造方法(基本概念、重写 init 方法、init 方法的执行过程、自定义)

  • 完整地创建一个可用的对象:1> 分配存储空间 +alloc,2> 初始化 - init (+ new 方法连续完成 1>、2> 步骤)
  • 基本概念:用来初始化对象的方法,是一个对象方法, 号开头,init 方法就是构造方法
  • 重写 init 方法:一定要调用回 super 的 init 方法。重写目的:为了让对象创建出来,就使成员变量具有固定的值
  • 1 //----Student.m-------------
  • 2 - (id)init {
  • 3 if (self = [super init]) //调用回super的init方法,返回对象self,即isa为Student对象
  • 4 { //初始化成功
  • 5 _age = 10;
  • 6 }
  • 7 return self;
  • 8 } 
1 //------NSObject------------
2 - (id)init {
3     isa = [self class];
4     return slef;
5 }
  • init 方法的执行过程:先初始化父类,再初始化子类。
  • 自定义:规范:1>一定是对象方法,一定以 - 开头,2>返回值一般为 id 类型,3>方法名一般以 init 开头
  • 初始化的好习惯:初始化成员变量在其所在类实现中进行(优点:去耦合。即当父类改变成员变量名称,就不用改子类的代码)

 


六、更改 Xcode 模版(main.m 、注释)

  • main.m:如 Mac application的终端项目:进入/Users/jackieyi/Library/Developer/Xcode/Templates/Project Templates/Application/Command Line Tool.xctemplate/Templateinfo.plist,按需要修改这个plist文件即可。
  • 注释:如 Mac Application的终端项目:进入/Users/JackieYip/Library/Deverloper/Xcode/Templates/File Templates/Cocoa/Objective-C class.xctemplate/NSObject/___FILEBASENAME___.m,或按需要选对应文件进行修改即可。

 


七、分类(基本使用、使用注意、给 NSString 增加类方法及扩充对象方法)

  • 作用:在不改变原来类内容的基础上,可以为类增加一些方法
  • 注意:1> 只能增加方法,无法增加成员变量,但在分类的方法中可以访问原类的成员变量
    • 2> 分类可以重新实现原来类中的方法,但是会覆盖原来的方法,会导致原来的方法无法再使用
    • 3> 方法调用的优先级:高|分类(最后参与编译的分类优先)->原类->父类|低
      • 编译顺序的查看:项目-TARGETS - Builde Phases - Complie Sources,由上往下顺序编译(全为 .m 文件,.h 文件不参与编译)

 


八、类的深入研究(本质、类对象的使用、类的加载和初始化)

  • 本质:我们知道:每个对象都有类型。而类本身也是一个对象,简称“类对象”,“类对象”的类型为 Class 类型(Class包含*)。
    • 由“类对象”创建的对象称为“实例对象”。
    • “类对象”默认只有一份被加载到内存中,“实例对象”可以有多份被加载到内存中(不同的“实例对象”,其isa始终指向其同一“类对象”)。
1 Student *stu = [[Student alloc] init];
2 Class stu1 = [stu class];                //利用Class创建Student类对象,[stu class]是获取内存中的类对象
3 Class stu2 = [Student class];        //stu1的地址等于stu2的地址,都是stu的地址
  • 使用:“类对象”可以调用“类方法”
  • 加载:属于运行时机制。当程序启动的时候,就会加载一次项目中所有的类和分类(无论有无使用类)。类加载完毕之后就会调用 + load 方法,只调用一次(先加载 父类 ,再加载 子类,最后加载 分类 )
1 + (void)load {
2      //程序一启动,所有的类都调用这个加载方法
3 }        
  • 初始化:属于运行时机制。当第一次使用类的时候,就会调用一次 + initialize 方法(先初始化 父类 ,再初始化 子类 ,如果有 分类 ,只会初始化 分类 ) 
1 + (void)initialize {
2      //第一次使用类的时候([[类 alloc]init]),就会调用一次这个方法。我们可以在这里监听类何时被使用
3 }

 


九、description 方法

  • 默认情况下,利用 NSLog 和 %@ 输出 类对象 的时候,结果是:<类名:内存地址>
  • 每次调用 NSLog (@"%@",“实例对象”) 的时候,会默认调用“实例对象”的 - description 方法, - description  方法的返回值为 (NSString *),默认返回的是"类名+内存地址"
  • 可以重写 - description 方法输出所有 成员变量
1 - (NSSting *)description {
2         //  NSLog(@"%@",self);        //这行代码会引发死循环
3         return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];
4 }
  • 每次调用 NSLog (@"%@",“类对象”) 的时候,会默认调用“类对象”的 + description 方法,+ description  方法的返回值为 (NSString *),默认返回的是"类名"
  • + description 也可以被重写

 


十、NSLog 输出补充

1 int main() {
2     NSLog(@"%d",__LINE__);        //输出当前行号(即 2 )
3     //NSLog(@"%s",__FILE__);        //NSLog输出 C 语言字符串的时候,不能有中文
4     printf(@"%s\n",__FILE__);        //输出源文件的名称(含路径)
5     NSLog(@"%s\n",__func__);        //输出当前函数名(即 main )
6 }

 


十一、SEL (基本用法及其他使用)

  • 属于运行时机制。一个 SEL 代表一个方法,对应方法地址
  • 对象调用 方法 时:1> 先把 方法 包装成 SEL 类型的数据,2> 根据 SEL 数据找到对应的 方法地址,3> 根据 方法地址 调用对应的方法
1 int main() {
2     Student *stu = [[Student alloc] init];
3     [stu test]; 
4     [stu performSelector:@selector(test)];        //间接调用test方法,@selector(test)就是一个SEL类型
5     [stu performSelector:@selector(test1:) withObject:@"123"]; //间接调用test:方法,@selector(test:)就是一个SEL类型
6 }
1 NSString *name = @"test";
2 SEL s = NSSelectorFromSrting(name)        //将test方法包装成SEL数据
3 [stu performSelector:s];
  • 每个方法里面都有一个 SEL 类型数据的_cmd,_cmd代表当前方法。给对象传递消息,其实就是给对象传递 SEL 数据。SEL 不能直接打印,只能转成字符串进行打印。
1 - (void)test {
2     NSString *str = NSStingWithSelector(_cmd);
3     NSLog(@"调用了test方法---%@",str);        //显示:调用了test方法---test
4 }