"OC基础"这个分类的文章是我在自学Stephen G.Kochan的《Objective-C程序设计第6版》过程中的笔记。
1、有时候初始化需要让对象带有初始值,那么可以定义另一个初始化方法来使用,比如:
-(XCLASS *) initWith: (int) n {
self = [super init];
if(self) {
[self setFunction: n]; // setFunction方法是指XCLASS定义的赋值方法
}
return self;
}
这个方法的意思是:首先用父类的init方法先把对象初始化,然后用if(self)判断是否初始化成功(初始化成功则self不为空,判断条件成立;注意没初始化的话,self的值是空的),成功则使用赋值方法给对象赋值,那么这就是一个带赋值的初始化方法了。
同时为了方便使用,甚至可以再进一步重载init方法,如下:
-(instancetype) init {
return [self initWith: 0];
}
那么当使用init方法的时候,就会自动使用重载过的方法,给对象赋初始值0。方法的返回类型instancetype表示未确定具体返回类型,因为你不知道使用重载过的init方法的会是哪一个继承后的类。重载init方法有一个标准模板,如下:
-(instancetype) init {
[super init];
if(self){
…
}
return self;
}
2、关于几种变量的理解:
(1)、局部变量:语句块内部的变量,比如方法内部的变量,当方法运行的时候才存在。局部变量默认初始化为nil,它们是没有“记忆力”的,比如方法的局部变量,每次方法返回后,它们的值就消失了,重新调用方法的时候,这些局部变量都会重新初始化以此。方法的参数也是局部变量;
(2)、实例变量:即是对象所包含但不属于某个方法的变量,在多个不同方法调用的过程中会保持自己的值,在对象存在的过程中实例变量一直跟随存在。不同的对象都会有自己的一套实例变量,哪怕它们是同个类的;
(3)、静态变量:用static修饰的变量是为静态变量,它的值会一直存在,甚至可以跨越不同的实例,即是说,不同的实例可以去修改它的值,并且会共同累加;
(4)、全局变量:在文件中所有方法和类之外的地方定义的变量,在这个模块中任何位置都可以引用这个变量的值。全局变量一般以g开头;
(5)、外部变量:当你访问其他文件定义的全局变量的时候,那么这个全局变量对你来说就是外部变量,你需要先把它声明一遍,使用语法类似:
extern int gXxx;
然后才可以给它赋值使用,不能在声明后立刻跟上等号进行赋值,会报错。
3、如果使用static把全局变量声明为静态变量,则只有这个文件中在这个声明语句后面的方法可以访问这个变量,其他文件中的方法就访问不了。
4、关于属性和实例变量:
(1)、属性是指用@property和@synthesize声明过的变量,这些属性可以直接用点运算符代替setter方法和getter方法;而实例变量必须配合setter方法和getter方法才能访问,没法直接访问;
(2)、声明属性之后会自动生成对应的实例变量(不过代码没有显式地表达处理)。如果只使用@property而没有使用@synthesize,那么xxx对应的实例变量是_xxx,注意是有下划线的。
5、关于枚举数据类型:
(1)、枚举数据类型使用enum来定义,如语句:
enum flag {true, false};
定义了数据类型flag,而声明为flag类型的变量只能有两个值,true或者false。声明称枚举数据类型的格式如下:
enum flag xxx;
注意enum仍然要跟着;
(2)、枚举数据类型里的各个标识符,其实是被编译器当做整型数来处理,第一个标识符被赋值为0,接下来的依次递增。在代码中有主动赋值的标识符,可以改变默认的递增值,没有主动赋值的,会根据前一个值递增,如下:
enum direction {up, down, left=10, right};
四个值依次被赋值为0、1、10、11;
(3)、不同的标识符可以共享同一个值,如下:
enum boolean {no=0, false=0, yes=1, true=1};
(4)、定义一个枚举数据类型month,分别把十二个月对应为12个整数,那么假设有如下代码:
enum month thisMonth;
thisMonth = December;
那么以下代码是可以运行的,即是可以直接把标识符当做整型数来运算:
lastMonth = (enum month) (thisMonth – 1);
(5)、可以在声明枚举数据类型的时候不给它命名,同时直接声明一个该类型的变量,如下:
enum {east, west, north, south} direction;
并没有指定这个枚举类型的名称,同时直接声明了一个此类型的变量direction。
6、关于typedef语句:typedef语句用来给已有的数据类型指派另一个名称,可以增加代码的可读性。比如某个整型的变量n在程序中是要用作计数器,那么可以用以下代码:
typedef int Counter;
那么当使用Counter n来声明n 的时候,就能很清晰知道n是要用作计数器,虽然这个语句的效果是和int n一样的。
7、在表达式求值中的数据遵守以下的转换规则:不同类型的操作数在运算时,会统一转换成精度高的类型进行运算,计算出来的结果也是高精度的类型。以下的数据类型中越靠前的精度越高:
(1)、long double
(2)、double
(3)、float
(4)、long long int
(5)、long int
(6)、int
(7)、Bool、char、short int、bit field、enum
注意:第(7)的数据类型在运算时全部会转换成int类型。
8、位运算符:
(1)、位运算符可以处理任何类型的整型值,但不能处理浮点数。数据会被转化为二进制表示法进行运算;
(2)、与运算(&):两个二进制数相对应的位置进行运算,只有当两个数对应位置都为1时结果才为1,其他情况都为0。即是AND运算;
(3)、或运算(|):两个二进制数相对应的位置进行运算,只有当两个数对应位置都为0时结果才为0,其他情况都为1。即是OR运算;
(4)、异或运算(^):相同为0,相反为1。XOR运算;
(5)、一次求反运算(~):所有的位的值全部反过来;
(6)、向左移位运算(<<):所有位向左移一位,超出数据项的高位的位将丢失,低位移入的位值为0;
(7)、向右移位运算(>>):把值向右移一位,低位的数据将丢失。对于无符号的数,左边移入的值为0。对于有符号的数,如果最左边的位为0(正数),移入的也会是0,如果左边的数是1(负数),有些计算机会移入1(算术右移),有些计算机会移入0(逻辑右移)。
(8)、DeMorgan规则:~(~a&~b) == a|b,~(~a|~b) == a&b。