@property和@synthesize

@property和@synthesize:

假设我们要做5个数的加法运算(即有5个实例变量),那是否应该声明10个方法,即分别声明各个属性的设置和取得方法,这样做是不是很麻烦?幸好从OC 2.0开始,我们能让系统自动生成设置变量值的方法和获取变量的值的方法。通过这个功能,可以减少编码量,并将更多的精力放在程序的业务逻辑上,在接口文件中(也即是拓展名为.h的文件)使用@property来标示属性(一般是实例变量);在实现文件中(也即是拓展名为.m的文件)使用@synthesize标识所声明的属性,让系统自动生成设置方法和获取方法,下面通过一个例子看一下@property和@synthesize的程序:


声明文件Person.h:

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
    // int age;
    
    int _height;
    
    double _weight;
    
    NSString *_name;
}

// @property:可以自动生成某个成员变量的setter和getter声明
@property int age;
//- (void)setAge:(int)age;
//- (int)age;


@property int height;
//- (void)setHeight:(int)height;
//- (int)height;

- (void)test;


@property double weight;

@property NSString *name;

@end

实现文件Person.m:

#import "Person.h"

@implementation Person

// @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量
@synthesize age = _age;

@synthesize height = _height;

@synthesize weight = _weight, name = _name;

@end

类测试文件:

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Cat.h"
#import "Dog.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Dog *d = [Dog new];
        
        d.age = 5;
        
        NSLog(@"%d", d.age);
    }
    return 0;
}


定义@property的标准语法格式是:

@property (属性列表) 实例变量;

在我们的上面的例子中,属性列表没有设置任何属性


控制set方法的内存管理
retain : release旧值,retain新值(用于OC对象)
assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
copy   : release旧值,copy新值(一般用于NSString *)
 
 控制需不需生成set方法
readwrite :同时生成set方法和get方法(默认)
readonly  :只会生成get方法
 
 多线程管理
atomic    :性能低(默认)
nonatomic :性能高
 
控制set方法和get方法的名称
setter : 设置set方法的名称,一定有个冒号:
getter : 设置get方法的名称


下面以Cat为例简单说明:

main.m

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Cat.h"
#import "Dog.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Dog *d = [Dog new];
        
        d.age = 5;
        
        NSLog(@"%d", d.age);
    }
    return 0;
}


cat.h:

#import <Foundation/Foundation.h>

@interface Cat : NSObject
{
    //int _age;
    //int age;
}
@property int age;
@end

cat.m

#import "Cat.h"

@implementation Cat

// 默认会访问age这个成员变量,如果没有age,就会自动生成@private类型的age变量
@synthesize age;


@end


@property

用在@interface中

用来自生成setter和getter的声明

用@property int  age;就可以代替下面的两行

- (int)age;  //getter

-  (void)setAge : (int )age;//setter


@synthesize

用在@implementation中

用来自动生成setter和getter的实现

用@synthesize age = _age;就可以代替

- (int)age

{

return _age;

}

- (void )setAge : (int)age

{

_age = age;

}


@synthesize的细节

@synthesize age = _age;

setter 和getter 实现中会访问成员变量_age

如果成员变量 _age不存在,就会自动生成一个@private的成员变量_age

@synthesize age;

setter 和getter 实现中会访问成员变量_age

如果成员变量 _age不存在,就会自动生成一个@private的成员变量age

手动实现

若手动实现了setter方法,编译器就会自动生成getter方法

若手动实现了getter方法,编译器就会自动生成setter方法

若同时手动实现了setter和getter方法,编译器就不会自动生成不存在的成员变量


@property新特性:

自从Xcode4.4后,@property就独揽了@synthesize的功能,也就是说,@property可以同时生成setter和getter的声明和实现

默认情况下,setter和getter方法中的实现,会去访问下划线_开头的成员变量


#import <Foundation/Foundation.h>

@interface Dog : NSObject
@property int age;
@end

#import "Dog.h"

@implementation Dog


- (void)setAge:(int)age
{

}

//- (int)age
//{
//    
//}

//- (int)age
//{
//    return 10;
//}

@end

id类型:

在OC中,id类型是一个独特的数据类型。在概念上,类似于Java的Object类,可以装换为任何数据类型。换句话说,id类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。例如,下面定义了一个id类型的变量和返回一个id类型的方法:

-(id) newObject : (int) type;

id 和void *并非完全一样,下面是id在objc.h中的定义:

typedf struct objc_object

{

Class isa;

} *id;

从上面看出,id 是指向struct  objc_object的一个指针。也就是说,id 是一个指向任何一个继承了Object类的对象。需要注意的是id 是一个指针,所以在使用id的时候不需要加星号,比如:

id foo =  nil;

上述语句定义了一个nil指针,这个指针指向NSObject 的任意一个类,而”“id *foo = nil;”则定义了一个指针,这个指针指向另一个指针,被指向的这个指针指向NSObject的一个类。

在OC中,id 取代了int类型称为默认的数据类型,关键字nil被定义为空对象,也就是值为0的对象。

下面距离说明:

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;
@property id obj;
@end

Person.m

#import "Person.h"

@implementation Person

@end


main.m

#import <Foundation/Foundation.h>
#import "Person.h"


void test(id d)
{
    
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Person *p = [Person new];
        //[p fsdfdsfd];
        
        NSObject *o = [Person new];
        
        
        // id  == NSObject *
        // 万能指针,能指向\操作任何OC对象
        id d = [Person new];
        
        [d setAge:10];
        
        [d setObj:@"321423432"];
        
        NSLog(@"%d", [d age]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值