OC_04_属性_点语法_MKC

来源:互联网 发布:mysql 排序 编辑:程序博客网 时间:2024/05/29 13:55


属性

属性Objective-C 2.0定义的语法,为实例变量提供了settergetter⽅方法的默认实现

能在一定程度上简化程序代码,并且增强实例变量的访问安全性。

属性的定义

属性的声明:使用@property声明属性

例如:@property NSString *name;相当于@interface中声明了两个方法(settergetter):

- (void)setName:(NSString *)name;- (NSString *)name; 

声明属性的关键词是@property,后面对应的属性类型和属性声明

属性一共完成了三件事,一是声明了设置器和访问器,二是实现了设置器和访问器,三是声明了一个相对应的成员变量,属性名前加一个_(有了这个特性,可以不需要在@interface里声明成员变量)

如:

在.h里

@property NSString *stuName; //这里属性里的属性是默认的

@property (readwrite,setter = king:,getter = queen)NSInteger stuAge;

@property (nonatomic,assign)CGFloat stuScore; //基本数据类型

@property (nonatomic,copy)NSString *stuHobby;

@property (nonatomic,copy)NSString *stuSex;


在.m里

//自定义初始化

- (id)initWithStuName:(NSString *)stuName

               stuAge:(NSInteger)stuAge

             stuScore:(CGFloat)stuScore

             stuHobby:(NSString *)stuHobby

               stuSex:(NSString *)stuSex

{

   self = [superinit];

   if (self) {

       _stuName = stuName; //系统会自动为我们生成_stuName,以及以下成员变量

       _stuAge = stuAge;

       _stuScore = stuScore;

       _stuHobby = stuHobby;

       _stuSex = stuSex;

    }

    return self;

}



//遍历构造器

+ (id)studentWithStuName:(NSString *)stuName

                  stuAge:(NSInteger)stuAge

                stuScore:(CGFloat)stuScore

                stuHobby:(NSString *)stuHobby

                  stuSex:(NSString *)stuSex

{

   Student *stu = [[Studentalloc]initWithStuName:stuNamestuAge:stuAgestuScore:stuScorestuHobby:stuHobbystuSex:stuSex];

   return stu;

}




声明后我们可以在main文件里直接调用getter,setter方法

如:

    Student *stu = [[Studentalloc]init];

    [stusetStuName:@"king"];//setter

   NSLog(@"%@", [stustuName]);//getter


属性的实现(在新的Xcode版本中已经不需要@synthesize)

属性的实现:使⽤用@synthesize实现属性

例如:@synthesize name = _name;

相当于@implementation实现了settergetter

- (void)setName:(NSString *)name{...} 


属性的属性

Objective-C提供属性的目的是为了简化程序员编码

为属性提供了一些关键字用以控制settergetter的实现细节

这些关键字我们称为属性的属性(attribute)一共3大类attribute。 

第一类:读写性控制(readonlyreadwritesettergetterreadwrite是读写性控制的默认设置。 

属性的属性设置成readonly之后,只有访问器,没有设置器,属性没有属性默认是readwrite

setter = method相当于给setter方法进行改名,方法名别忘加:

系统一般对BOOL类型的属性进行改名,增加属性的可读性。如下声明:

@property (readwritesetter = king:, getter = queen)NSInteger stuAge;

则在main里,setter 变为 king, getter 变为 queen

[stu king:23]; //setter的新名字

    NSLog(@"%ld", [stu queen]); //getter的新名字


第二类:原子性控制(nonatomicatomic)

atomicsettergetter⽅方法在多线程访问下是绝对安全的,即settergetter内部做了多线程访问处理。原子性控制的默认设置是atomic

nonatomicsettergetter方法内部不会做多线程访问处理,仅是普通的settergetter⽅方法 

程序开发过程中,settergetter处处都在用,如果使用atomic,需要不断的对settergetter加锁解锁(这里是线程机制)以保证线程访问安全,会很占用系统资源,降低系统性能。通常设置为nonatomic,某些属性需要线程安全的时候,才定义为atomic

例如:@property (readwrite,nonatomic)NSString *name;//等价于

- (NSString *)name;
- (void)setName:(NSString *)name; 


属性的属性第二种,原子性设置

默认是atomic,可以时时监控事务,但是我们只是做一个简单的赋值操作,不需要监控,所以一般情况下设置成nonatomic,非原子性


第三类:语义设置(assignretaincopy)

assignsettergetter内部实现是直接赋值。 retain

settergetter的内部实现会做内存优化。

copysettergetter的内部实现也会做内存优化。 

如果属性是非对象类型(比如int,float等)属性的语义设置使用

assign。如果属性是对象类型(比如NSStrngNSArray等)属性的语义设置使用retain

如果属性是对象类型并且想得到参数的copy,使⽤用copy关键字 

内存管理:

alloc使引用计数由01(堆区)

retain使引用计数+1(堆区)

assign 不使用引用计数(栈区,自动)


属性的属性第三条语义设置

assign一般式CGFloat,NSIntegr这种基本数据类型,在栈区,我们使用assign


copy只有NSString *使用

retain 我们自己创建的类和系统的类所对应的对象用retain


点语法

点语法Objective-C 2.0中定义的语法格式。提供了一种便捷的属性访问方式

凡是符合系统默认settergetter书写格式的方法都可以使用点语法。 

如: Student *stu = [[Studentalloc]init];

    [stusetStuName:@"king"];  

   NSLog(@"%@", [stustuName]);

等价于

    stu.stuName =@"king";

   NSLog(@"%@", stu.stuName);

属性是一对gettersetter方法,点语法是属性的另一种调⽤用格式。 

点语法区分settergetter就是找,是否有等号,有冒号(:)就是setter,没有等号就是getter

一般用点语法来操作属性里的gettersetter,如果点多的方法,只有离=号最近的是一个setter,其余的都是getter(一层一层的往下寻找对应的方法)

例:self.windows.background.color = @"red";   // 只有.color是getter方法

属性声明的成员变量都是私有的


KVC

KVC(Key-Value-Coding),键值编码,是一种间接访问实例变量的方法。key:,⽤用于标识实例变量vlaue:实例变量对应的值 


修改值

setValue:forKey:

setValue:forKeyPath:

setValue:forUndefinedKey:

setValuesForKeysWithDictionary: 


获取值

valueForKey:

valueForKeyPath:

valueForUndefinedKey:


注意事项:

key不存在的时候,会执⾏行setValue:forUndefinedKey://value的值打错之类的

系统默认实现是抛出一个异常

//KVC

    // key-value-coding,间接对属性进行赋值

    Teacher *t = [[Teacheralloc]initWithTName:@"king"tAge:23tSex:@"m"tHobby:@"dota"tNum:88888];//以定义初始化方法的Teacher类

   NSLog(@"%@",t.tName);

    [t setValue:@"queen"forKey:@"tName"];

   NSLog(@"%@",t.tName);

    NSLog(@"%@", [tvalueForKey:@"tSex"]);


总结:

属性是Objective-C的重要语法,属性是一组gettersetter方法,内部对实例变量进⾏行操作。

点语法是一种属性的另外一种调用格式。

KVC是一种间接访问实例变量的方法。 






 









 
0 0
原创粉丝点击