自学OC的第二天

152 阅读4分钟

Day2

属性

类似java中的Lombok下的@Data注解(但是也有不一样的,@Data不仅生成get/set函数,同时也会生成多个构造函数。而OC中的属性只会生成get/set)。

使用方法就是通过@property对于属性进行声明。eg.

@interface interfaceA:NSObject{
	float attributeA;	//似乎可以缺省
	float attributeB;
}

@property float attributeA;
@property float attributeB;
@end
@implementation interfaceAImpl
@synthesize attributeA;	//编译器会自动生成-setAttributeA和-attributeA方法的预编译代码
@synthesize attributeB;

//...other method
@end

@property的参数

一共有四组参数:

  1. 与多线程相关的参数。

    atomic、nonatomic。

    atomic:会加上安全锁。(sync)

    nonatomic:没有安全锁,不安全,但是效率会较高。

  2. 与生成的setter方法相关的参数。

    assign、retain。

    assign:默认值,生成的setter方法实现就是直接赋值。

    retain:生成的setter方法就是标准的MRC内存管理代码。注意,不会在dealloc中生成release的代码,所以还是需要手动添加。

  3. 与生成只读,读写相关的参数。

    readonly、readwrite。

    readwrite:默认值。代表同时生成get函数和set函数。

    readonly:只会生成getter,而不会生成setter。

  4. 与生成的getter、setter方法名字相关的参数。

    getter、setter。

    默认情况下,@property生成的getter和setter方法的名字都是最标准的名字。

    getter = getter方法的函数名。用来指定@property生成的getter方法的名字。

    setter = setter方法的函数名。用来指定@property生成的setter方法的名字。但是需要注意,setter方法是需要参数的,后面需要加上一个冒号。

点表达式

如果其出现在“=”左边,则是调用相应变量的set方法。如果其出现在“=”右边,则是调用该变量的get方法。

classA.attributeA=20f;	//[classA setAttributeA:20f];
classA.attributeB=40f;	//[classA setAttributeB:20f];

属性修饰

需要将所有的属性特性显式的声明出来,特性的顺序为atomicity(nonatomic,atomic)、storage(weak,strong,assign)、rw(readonly,readwrite);并且NSString需要使用copy的属性特性而非strong。

类别

这部分是OC中新加的内容,需要之后抽时间进一步认真学习。现在只是了解,并未完全熟悉。

使用时机:

  1. 无法(不允许)修改主类,但是需要对主类中的方法进行一次拓展,添加方法,这时可以通过类别向主类添加一个方法而不用改变主类。
  2. 将一个大型的类分为多个类别,通过这种方法可以把不同类的方法放入不同的类别,从而将类的实现写入多个 .m的实现文件中,从而便于开发。
  3. **类别中的方法可以只声明,不实现。**可以作为非正式协议来使用。

使用方法:

新建类别文件的命名:“原类名 + 类别名”。

@interface NSString(categoryA,categoryB)
//注意,只能定义方法。
@end
@implemenation NSString(categoryA,categoryB)
//方法的实现
@end

不足:

  1. 只能添加方法,不能添加变量。
  2. 当类别中的方法和主类中的方法同名,类别中的方法优先级更高。

类拓展

类拓展是类别的一种特殊形式。

使用方法:

@interface  主类类名()//不需要类别名

@end

拓展类通常定义在主类的.m文件中,而在.m文件中实现。

内存管理的原则

  1. 有对象的创建,就要一个release。

  2. retain和release的次数要匹配。

  3. 谁用谁retain。谁不用谁release。

    谁负责retain,谁就负责release。

  4. 多一个用的时候才retain,少一个的时候才release。

  5. 在方法中不能随意进行retain。

野指针/僵尸对象

野指针:指针指向的对象已经被回收了。

僵尸对象:一个已经被释放的对象,其内存空间还没有被分配给别人。

检测僵尸对象功能不打开。消耗性能较高。

当一个指针成为野指针之后,将其值赋为nil。

当属性是一个OC对象的时候

第一步,将原本指向的对象进行release,然后再将新传入的对象进行retain。PS. 在新旧对象是同一个对象的时候,什么都不能做。

再赋值。而当前对象销毁的时候,则需要在dealloc中进行release。

当一个对象为nil的时候,调用方法函数不会有任何反应。

- (void)setCar:(Car *)car{
	if(_car != _car){
		[_car release];
		_car = [car retain];
	}
}

-(void)dealloc{
	[_car release];
	[super dealloc];
}