【Objective-C 篇】 ☞ 3. self、数据类型、编码规范
1. self关键字
self 是一个指针,哪个对象调用方法就指哪个对象,其作用是区分不同对象。
1.1 在实例方法中的self,代表当前对象
当前对象,通过哪个对象调用了这个方法,方法中的self就指向那个对象。这个对象就叫当前对象.
1.2 在类方法中的self,代表当前类
类方法中,self代表类方法所在的类本身。所以在类方法中,self会被直接当类来使用
我们推荐在类方法使用self代替类,因为便于子类继承
总结:
如果self在对象方法中,那么self就代表调用当前对象方法的那个对象
如果self在类方法中,那么self就代表调用当前类方法的那个类
我们只用关注self在哪一个方法中,如果在类方法那么就代表当前类,如果在对象方法那么就代表"当前调用该方法的对象"
super关键字
super 也是一个指针,指向当前类的对象中父类的成员。
- super代表类的父亲
- [super init]是通知父类区做底层的初始化操作。
- super是指向对象中继承过来的父类部分的指针。
- 利用super可以调用由于子类重写而被隐藏的父类函数。
2. OC中对象类型和非对象类型
2.1 概念
1) 对象类型,@interface定义的类,可以创建对象。所以这种类型叫对象
2) 非对象类型,OC语言是完全兼容C语言,所以C语言中的基本数据类型,结构体,枚举等在OC都可以用,这些类型叫非对象类型。
2.2 内存分配
1) OC中所有的对象都在堆中。但指向对象的引用可能在栈中,当然也可能在全局区,或堆中。
2) OC中所有的对象类型的参数传递都是地址传递,我们只能将对象的地址传给一个函数或方法,不可能将对象本身传给函数或方法。
3) OC中的非对象类型,内存分配可能会在栈中,或全局区。也可能在堆中(当做为一个对象的属性时)
3. OC语言中经常使用的非对象类型
3.1 基本数据类型
NSInteger:
typedef int NSInteger;(32位系统)
typedef long NSInteger;(64位系统)
在32bit的iOS系统中,NSInteger是4个字节,而在64bit系统中,是8个字节。这样做的兼容性好。
所以,在iOS实际开发中,尽量使用NSInteger来定义变量,属性,参数等,而不要使用int或long等。
NSUInteger: 是无符号的NSInteger
typedef unsigned int NSUInteger;(32位系统)
typedef unsigned long NSUInteger; (64位系统)
CGFloat:
在32bit的iOS系统中,CGFloat是4个字节,相当于float类型;而在64bit系统中,是8个字节,相当于double,这样做的兼容性好。
所以,在iOS实际开发中,尽量使用CGFloat来定义变量,属性,参数等,而不要使用float或double等。
typedef double NSTimeInterval; //NSTimeInterval 是double类型,通常用于表示时间(多少秒)
BOOL:
逻辑数据类型BOOL
C语言中布尔类型:bool b1 = false; //true 1 false 0
Objective-C中布尔类型: BOOL b2 = YES; //YES 1 NO 0
3.2 结构体:CGPoint、CGSize、CGRect、NSRange
3.3 实际的iOS开发中经常定义的全局常量
需要在一个文件中声明全局常量,再在一个.m文件中定义全局常量。这个常量就可以在应用的任何位置使用了。使用前需要#import头文件
3.4 枚举
OC语言中使用的枚举就是C语言中的枚举
OC语言现在使用枚举都是按照C++11的标准规范定义。C++11中规定,枚举值可以规定类型。
enum 枚举类型名 : 枚举值类型{枚举值...};
OC语言中定义枚举使用新的方式:
typedef NS_ENUM(枚举值类型, 枚举名){...};
typedef NS_OPTIONS(枚举值类型, 枚举名){...};
4. OC语言基本编程规范
怎么定义类名,方法名,属性名,代码风格....
4.1 标准符(identifier )
给类,属性,方法,变量,结构体,枚举等起的名字
最基本的规定,违反规定会导致编译错误
1) 必须以字母或下划线开头
2) 可以包含字母、下划线和数字
+-*/肯定是不行的
3) 不能和关键字冲突 float int = 3.14;//ERROR
4) 大小写敏感(case sensitive)
5) 长度不限
4.2 命名规范
1)类,分类,扩展,协议,结构,枚举等类型起名时,一般要加前缀
TRMyFirstClass: TR是前缀
NSString : NS是前缀
CGPoint : CG是前缀
UIButton : UI是前缀
主要目的是减小命名冲突。苹果公司默认保留所有两个字母前缀的权利,所以非苹果官方的类建议都使用三个字母的前缀。
2)使用驼峰命名方式
- 给类,分类,扩展,协议,结构,枚举等类型起名时,每个单词的首字母大写。(如:TRMyFirstClass)
- 给属性、方法、变量起名时,第一个单词的首字母小写,其他单词的首字母大写。
mySalary
setName:
isGirl
changeYourName:
3) 一般使用#define定义的宏都是大写的
但是,OC中,不建议大量使用宏。如果要定义常量,应该在头文件中声明,在.m中定义,命名使用驼峰方式
4.3 特殊方法的命名
1)初始化方法
无参的初始化方法一定叫"init"
有参的初始化方法一定以"initWithXxx.."开头,后面单词首字母大写
2)工厂方法
绝大部分工厂方法的名字都是类名开头(首字母小写),如果有参数,加With
+ point
+ pointWithX:...
有特殊含义的方法可以不遵守这个规定,比如
UIColor类中的 red, green, blue等类方法
3) 普通方法
普通的实例方法和类方法尽量不要以new开头。因为以new开头的方法往往是用来创建对象的,系统会做特殊的内存管理。
[TRPoint new]; ==> [[TRPoint alloc]init];
4.4 其他需要注意的事项
1) 代码一写要有缩进,代码就有层次感
2) 当一个方法的参数较多时,可以分多行,每行将用":"号对齐
3) 方法不要太长,争取一屏能显示得下一个方法的所有代码
如果方法太长,可以拆成若干个私有方法。
5. @class
- #import:
- 由于import是一个预编译指令, 他会将""中的文件拷贝到import所在的位置
- 并且import有一个特点, 只要""中的文件发生了变化, 那么import就会重新拷贝一次(更新操作)
- @class:
- @class仅仅是告诉编译器, @class后面的名称是一个类, 不会做任何拷贝操作
- 注意: 由于@class仅仅是告诉编译器后面的名称是一个类, 所以编译器并不知道这个类中有哪些属性和方法, 所以在.m中使用这个类时需要import这个类, 才能使用
- 在.h中用@class可以提升编译效率
是因为在.h中用@class,在.m中用import,如果一个文件发生了变化,只有和这个文件有直接关系的那个文件才会重新拷贝
Q:如果两个类相互拷贝,例如A拷贝B,B拷贝A,这样会报错
A:因为如果.h中都用import, 那么A拷贝B, B又拷贝A, 会形成死循环
如何解决?
在.h中用@class, 在.m中用import
如果在.h中用@class, 那么不会做任何拷贝操作, 而在.m中用import只会拷贝对应的文件, 并不会形成死循环
- 在实际开发中,在.h中要使用某个类建议用@class,在.m中要使用某个类用#import