属性是怎么达到减少代码数量的作用的
使用属性关键字,不需要太多的方法定义语句,因为多个方法里面可能都有相同属性的字段定义,只要使用属性关键字,不同的方法都可以对这个属性进行设置和访问.
头文件中这样使用:
#import <Foundation/Foundation.h>
#import "Tire.h"
@interface AllWeatherRadial : Tire
{
float rainHanding;
float snowHanding;
}
@property float rainHanding;
@property float snowHanding;
@end //AllWeatherradial
变量的声明
变量的声明既可以放在头文件中,也可以一部分放在头文件中,一部分在实现文件中声明.区别是如果想从子类中通过属性来访问变量,变量就必须放在头文件中,如果变量只属于当前类,则可以把它们放在.m文件里并且删除原interface中的声明语句.
实现文件中这样使用:
@implementationAllWeatherRddial
{
float rainhanding;
float snowHanding;
}
@synthesize rainHanding;
@synthesize snowHanding;
- (id) initWithPressure: (float)p treadDepth: (float)td
{
if(self = [super initWithPressure: p treadDepth : td])
{
rainHanding = 23.7;
snowHanding = 42.5;
}
return (self);
}//initWithPressure : treadDepth
- (NSString *) description
{
NSString *desc;
desc = [[NSString alloc] initWithFormat: @"AllWeatherRadial: %.1f / %.1f / %.1f / %.1f", [self pressure], [self treadDepth], [self rainHanding], [self snowHanding]];
return (desc);
} //description
@end //AllWeathRadial
@property 预编译指令的作用是自动声明属性的setter和getter方法.(简化的是声明),预编译指令告诉编译器对象具有这些类型的特性,还可以传递其他信息,如只读或只写.在后台会自动生成setter,getter的声明语句.
@synthesize 关键字表示创建了该属性的访问代码, 作用是自动添加setter和getter方法的实现部分的预编译代码(简化的是实现), 可以使用dynamic编写自己的访问方法.
OC中的ID类型
OC中的ID类型,相当于C语言中的void *, 又可以称为万能指针, 代表一个可以指向任何OC对象的指针, 是一个通用的对象类型,因为id是动态类型,所以可以通过id类型直接调用指向对象中的方法,编译器不会报错.
但是方法必须是存在的,如果使用id类型的调用本项目中所有类中都没有的方法,编译器会报错.
什么时候用指针/值传递
在对象初始化的时候发现有时候使用的是值,有时候使用的是指针,使用的原则如下:
判断标准是: 函数是否会对值进行修改。
对于那些函数,它们只使用传递过来的值,而不对值进行修改,则使用值传递:
(1)如果数据对象很小,如内置数据类型或小型结构,使用按值传递。
(2)如果数据对象是数组,则使用指向const的指针。
(3)如果数据对象是较大的结构,则使用const指针或者const引用,以提高程序的效率。
(4)如果数据对象是类对象,则使用const引用。因此,传递类对象参数的标准方式是按引用传递。对于那些函数,它们需要修改传递过来的值, 则使用指针:
(1)如果数据对象是内置数据类型,则使用指针。
(2)如果数据对象师叔祖,则只能使用指针。
(3)如果数据对象是结构。则使用指针或者引用。
(4)如果数据对象是类对象,则使用引用。
点表达式
使用点.访问对象的变量
tire.rainHanding = 20 + i;
如果点出现在=左边,相当于调用了该变量的setter方法,如果点出现在变量右边,则将调用变量的getter方法.
tire setRainHanding = 20 + i;
属性的扩展
copy特性和retain保留和释放特性
@property (copy) NSString *name;
@property (retain) Engine *engine;
编译器和类的使用者将会知道name的属性将会被复制;
engine的属性可以使用的只有保留和释放特性.
OC中assign、copy 、retain等关键字
属性nonatomic和atomic相关
如果没有为属性指定任何特性,它们会默认使用nonatomic,assign,
nonatomic: 非原子属性,不会为setter加锁,非线程安全,适合内存小的移动设备
atomic: 原子属性,为setter方法加锁(默认就是atomic),线程安全,需要消耗大量资源
iOS开发建议:
(1)所有属性都声明为nonatomic
(2)尽量避免多线程抢夺同一块资源
(3)尽量将加锁,资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力
atmoic并不能保证线程安全,只能说在编译器生成的getter和setter是原子操作,系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。getter 还是能得到一个完好无损的对象(可以保证数据的完整性),但这个对象在多线程的情况下是不能确定的.
可查看这篇文章iOS 深入了解 atomic 与
nonatomic
只读属性
默认情况下,属性是可变的,可读可写,使用时如下:
@interface Me : NSObject
{
float shoesize;
NSString *licenseNumber;
}
@property (readonly) float shoesize;
@property (readonly) NSString *licenseNumber;
@end
只读属性编译时只会生成一个getter方法而不会生成setter方法.
dynamic自定义属性
@dynamic可以告诉编译器不要去创建变量或getter,setter方法, 不存储值,而是创建一个能在运行时计算出此值的方法.
属性的默认值
如果是数值类型默认属性
atomic assign readwrite
如果是对象类型
atomic strong readwirte