黑马程序员――@property及其参数的详解
来源:程序员人生 发布时间:2015-08-12 08:28:50 阅读次数:3703次
------Java培训、Android培训、iOS培训、.Net培训、期待与您交换! ------
@property详解
1.甚么是@property?
@property是OC独有的1个关键字,它属于编译器1个特性,编译器碰到@property时,会自动展开为成员变量的set和get方法
在Xcode4.5之前,Xcode编译器碰到@property会将其转换为成员变量set、get方法的声明,碰到@synthesize会展开为成员变量set、get方法的实现,所以XCode4.5之前,@property与@synthesize是配对使用。在Xcode4.5以后,Xcode碰到@property关键字,其将自动帮我们转换为(成员变量的声明、相应set、get方法的声明与实现)。
2.我们怎样使用@property?
代码解释:
我们手动写的代码(关闭ARC机制):
@interface Person : NSObject
{
NSString *_name;
}
- (void) setName:(NSString *)name;
- (NSString *) name;
@end
@implementation Person
-(void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name retain];
}
}
-(NSString *)name
{
return _name;
}
-(void)dealloc
{
[_name release];
[super dealloc];
}
@end
Xcode4.5之前,利用@property与@synthesize配对写的代码
//Xcode 4.5以下的写法
@interface Person :NSObject
@property NSString *name;
/*
*@property NSString *name;这句展开为:
*{
* NSString *_name;
*}
*- (void) setName:(NSString *)name;
*- (NSString *) name;
*/
@end
@implementation Person
@synthesize name = _name;//这里必须要写 =_name,否则展开的代码会自动创建1个私有变量:NSString *name;(其他类不可访问(包括子类))
/*@synthesize name = _name;这句展开以下:(展开的是不符合内存管理的)
*-(void)setName:(NSString *)name
*{
* _name = name;
*}
*-(NSString *)name
*{
* return _name;
*}
*/
@end
Xcode 4.5以后的写法,只用关键字@property:
#import <Foundation/Foundation.h>
//Xcode 4.5以上的写法
@interface Person : NSObject
@property NSString *name;
/*
*@property NSString *name;这句在@interface中展开有:
*{
* NSString *_name;
*}
*- (void) setName:(NSString *)name;
*- (NSString *) name;
*
*@property NSString *name;这句在@implementation中展开有:
*
*-(void)setName:(NSString *)name
*{
* _name = name;
*}
*-(NSString *)name
*{
* return _name;
*}
*/
@end
@implementation Person
//Xcode4.5往后,都不用写@synthesize
@end
@propert的相干参数
1.@property有哪些参数?
第1组:retain assign copy strong weak unsafe_unretained autoreleasing
第2组:readwrite readonly
第3组:nonatomic atomic
第4组:setter getter
2.参数分别有何作用?
①参数说明
第1组(retain assign copy strong weak unsafe_unretained autoreleasing)用于:set方法内存管理
assign(默许参数):生成直接赋值的set方法(不斟酌内存管理),适用于非OC对象(基本数据类型、复合数据类型)
retain:生成符合内存管理的set方法(release旧值,retain新值),适用于OC对象的成员变量
copy:生成符合内存管理的set方法(release旧值,copy新值),适用于NSString、NSArray等不可变对象。
Strong:强援用,决定了对象的存亡(1个对象如果没有强指针指向(援用计数器为0)时,对象将被烧毁,释放内存),其指向1个对象,相当于该对象做了1次retain操作。适用于OC对象
weak:弱援用,其存在与否无所谓(弱指针指向对象与否(对象援用计算器不变)),适用于OC对象
unsafe_unretained:请查看:浪天涯的博客
注意:
weak与Strong1般在开启ARC机制下使用
Strong:强援用,决定了对象的存亡(1个对象如果没有强指针指向(援用计数器为0)时,对象将被烧毁,释放内存),其指向1个对象,相当于该对象做了1次retain操作。
非ARC的retain,相当于ARC的strong,弱援用相当于assign
使用copy参数与使用retain参数产生的set方法1致(将生成set方法中的retain改成copy便可)
第2组(readwrite readonly)用于:是不是要生成set方法
readwrite(默许参数):同时生成set、get方法的声明与实现
readonly:只生成get方法的声明与实现(不生成set的方法的声明与实现)
第3组(nonatomic atomic)用于:多线程管理
atomic(默许参数):原子性,性能低(1般开发OC中的APP不推荐使用,做金融等高安全的时候使用)
nonatomic:非原子性,性能高(强烈推荐使用,性能高)
atomic:(原子性操作)就是1个操作履行进程不能被中断, 要不就履行完, 要不就不履行(1个操作不可以被中途cpu暂停然后调度)。如果1个操作是原子性的,
那末在多线程环境下, 就不会出现变量被修改等奇怪的问题(保证数据同步)。原子操作就是不可再分的操作,在多线程程序中原子操作是1个非常重要的概念,它常经常使用来实现1些同步机制,同时也是1些常见的多线程Bug的源头。
nonatomic:(非原子性操作)操作是直接从内存中取数值(不斟酌其是不是被占用),由于它是从内存中获得数据,它并没有1个加锁的保护来用于cpu中的寄存器计算Value,它只是单纯的从内存地址中,当前的内存存储的数据结果来进行使用。在多线程环境下可提高性能,但没法保证数据同步。
第4组(setter getter)用于:set、get方法重命名(经常使用于BOOL类型的成员变量的get方法,BOOL方法常以is开头(set方法很少用))
setter:给成员变量的set方法重命名,set方法默许命名:- (void) set成员变量名(成员变量名首字母大写):(成员变量数据类型)成员变量名
getter:给成员变量的set方法重命名,get方法默许命名:- (成员变量数据类型) 成员变量名
②代码证明
参数实例示范:
main.m文件
/*
*第1组:retain assign copy strong weak
*第2组:readwrite readonly
*第3组:nonatomic atomic
*第4组:setter getter
*/
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Book.h"
int main(int argc, const char * argv[]) {
Student *stu = [[Student alloc]init];
Book *b = [[Book alloc]init];
Book *b1 = [[Book alloc]init];
/*******验证retain与assign********/
NSLog(@"b = %ld",[b retainCount]);
NSLog(@"b1 = %ld",[b1 retainCount]);
stu.book = b;
stu.book1 = b1;
NSLog(@"book(参数:retain)使用后b = %ld",[b retainCount]);
NSLog(@"book1(参数:assign)使用后b1 = %ld",[b1 retainCount]);
/***********验证readonly*****************/
//stu.age = 10;调用setAge方法报错,setAge方法不存在,说明没有生成setAge方法
//可以输出stu中age的值,说明生成了get方法
NSLog(@"Student age is %i",stu.age);
/***********验证setter与getter****************/
//可以调用stu的isMan方法,而我们又没有写setIsMan方法,说明重命名成功
stu.isMan = YES;
NSLog(@"%d",stu.isMan);
[b1 release];
[b release];
[stu release];
return 0;
}
Student.h文件
/*在非ARC(关闭ARC)下验证:
*第1组:retain assign copy strong weak
*第2组:readwrite readonly
*第3组:nonatomic atomic
*第4组:setter getter
*/
#import <Foundation/Foundation.h>
@class Book;
@interface Student : NSObject
/***********验证retain*************/
@property (nonatomic,retain,readwrite) Book *book;
/*以上使用retain参数,展开的set实现方法为:
*- (void) setBook:(Book *)book
*{
* if(_book != book)
* {
* [_book release];
* _book = [book retain];
* }
*}
**/
/***********验证assign*************/
@property (nonatomic,assign,readwrite) Book *book1;
/*以上使用retain参数,展开的set实现方法为:
*- (void) setBook:(Book *)book
*{
* _book = book;
*}
**/
/***********验证readonly*************/
@property (nonatomic,assign,readonly) int age;
/*以上使用readonly参数,只生成get方法:
*- (int) age;
*{
* return _age;
*}
**/
/***********验证setter与getter*************/
@property (nonatomic,assign,readwrite,setter=setIsMan:,getter=isMan) BOOL man;
/*以上使用setter参数,只生成set方法名被修改成:isMan
*- (void) isMan:(BOOL)man;(默许方法名为:man)
*{
* _man = man;
*}
*
*以上使用getter参数,只生成get方法名被修改成:isMan
*- (BOOL) isMan;(默许方法名为:man)
*{
* return _man;
*}
**/
@end
Student.m文件
#import "Student.h"
#import "Book.h"
@implementation Student
-(void)dealloc
{
[_book release];
NSLog(@"Student被烧毁!!");
[super dealloc];
}
@end
Book.h文件
#import <Foundation/Foundation.h>
@interface Book : NSObject
@property (nonatomic,copy,readwrite) NSString *name;
@end
Book.m文件
#import "Book.h"
@implementation Book
-(void)dealloc
{
[_name release];
NSLog(@"book被烧毁!!");
[super dealloc];
}
@end
参数结果输出:
2015-05-01 12:02:53.108 07-@property及其参数[2364:221860] b = 1
2015-05-01 12:02:53.109 07-@property及其参数[2364:221860] b1 = 1
2015-05-01 12:02:53.109 07-@property及其参数[2364:221860] book(参数:retain)使用后b = 2
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] book1(参数:assign)使用后b1 = 1
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] Student age is 0
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] 1
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] book被烧毁!!
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] book被烧毁!!
2015-05-01 12:02:53.110 07-@property及其参数[2364:221860] Student被烧毁!!
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠