Objective-C中属性的简单使用(存取方法)

我们知道写oc代码时可能会创建很多的类和对象,我们要修改对象的值时就使用oc的setter方法(设置属性值)和getter方法(读取属性值),代码量会很大,这就增加了写代码的时间。先来看看使用存取方法的一小段程序:

#import <Foundation/Foundation.h>


@interface Tire : NSObject

@end
@implementation Tire

-(NSString *)description
{
    return (@"I am a tire.I last a while");
}

@end

@interface Engine : NSObject

@end
@implementation Engine

-(NSString *)description
{
    return (@"I am an engine.Vrooom!");
}

@end

@interface Car : NSObject
{
    Engine *engine;
    Tire *tires[4];
}
//Engine类的getter方法
-(Engine *)engine;
//Engine类的setter方法
-(void)setEngine:(Engine *)newEngine;
//Tire类的getter方法
-(Tire *)tireAtIndex:(int)index;
//Tire类的setter方法
-(void)setTire:(Tire *)tire atIndex:(int)index;
-(void)print;

@end
@implementation Car

-(Engine *)engine
{
    return (engine);
}

-(void)setEngine:(Engine *)newEngine
{
    engine = newEngine;
}

-(Tire *)tireAtIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in tireAtIndex:",index);
        exit(1);
    }
    return (tires[index]);

}

-(void)setTire:(Tire *)tire atIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in setTire:atIndex:",index);
        exit(1);
    }
    tires[index] = tire;
}


-(void)print
{
    NSLog(@"%@",engine);
    NSLog(@"%@",tires[0]);
    NSLog(@"%@",tires[1]);
    NSLog(@"%@",tires[2]);
    NSLog(@"%@",tires[3]);
}

@end

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

    Car *car = [Car new];
    Engine *engine = [Engine new];
    [car setEngine:engine];
    for(int i = 0;i < 4;i++)
    {
        Tire *tire = [Tire new];
        [car setTire:tire atIndex:i];
    }
    [car print];
    return 0;
}

还好我们还可以简化这些代码,在接口声明中我们使用@property关键字,在实现中我们使用@synthesize关键字。代码如下:

#import <Foundation/Foundation.h>


@interface Tire : NSObject

@end
@implementation Tire

-(NSString *)description
{
    return (@"I am a tire.I last a while");
}

@end

@interface Engine : NSObject

@end
@implementation Engine

-(NSString *)description
{
    return (@"I am an engine.Vrooom!");
}

@end

@interface Car : NSObject
{
    Engine *engine;
    Tire *tires[4];
}
@property Engine *engine;


//Tire类的getter方法
-(Tire *)tireAtIndex:(int)index;
//Tire类的setter方法
-(void)setTire:(Tire *)tire atIndex:(int)index;
-(void)print;

@end
@implementation Car

@synthesize engine;

-(Tire *)tireAtIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in tireAtIndex:",index);
        exit(1);
    }
    return (tires[index]);

}

-(void)setTire:(Tire *)tire atIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in setTire:atIndex:",index);
        exit(1);
    }
    tires[index] = tire;
}


-(void)print
{
    NSLog(@"%@",engine);
    NSLog(@"%@",tires[0]);
    NSLog(@"%@",tires[1]);
    NSLog(@"%@",tires[2]);
    NSLog(@"%@",tires[3]);
}

@end

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

    Car *car = [Car new];
    //通过属性来设置Car对象里的成员,而不需要发送setter消息来设置(即不需要显示调用setter方法),而且这里我们使用了点运算符
    car.engine = [Engine new];
    for(int i = 0;i < 4;i++)
    {
        Tire *tire = [Tire new];
        [car setTire:tire atIndex:i];
    }
    [car print];
    return 0;
}

看上面的代码是不是简化了?@property是一种新的编译器功能,它意味着声明了一个新对象的属性。@property预编译指令的作用是自动声明属性的setter和getter方法,@synthesize也是一种新的编译器功能,它表示“创建了该属性的访问代码”。所有的属性都是基于变量的,所以你在合成setter和setter方法的时候,编译器会自动创建与属性名称相同的实例变量。假设你有一个子类,并且想要从子类直接通过属性来访问变量。在这种情况下,变量就必须放在头文件中。如果变量只属于当前类,则可以把它们放在.m文件里(并且要删除原interface代码中的声明语句)。还有,如果我们没有指定实例变量,编译器会自动帮我们创建。如下:

#import <Foundation/Foundation.h>


@interface Tire : NSObject

@end
@implementation Tire

-(NSString *)description
{
    return (@"I am a tire.I last a while");
}

@end

@interface Engine : NSObject

@end
@implementation Engine

-(NSString *)description
{
    return (@"I am an engine.Vrooom!");
}

@end

@interface Car : NSObject
{
    //Engine *engine;       //删除了声明的实例变量,但不会有任何影响
    Tire *tires[4];
}
@property Engine *engine;


//Tire类的getter方法
-(Tire *)tireAtIndex:(int)index;
//Tire类的setter方法
-(void)setTire:(Tire *)tire atIndex:(int)index;
-(void)print;

@end
@implementation Car

@synthesize engine;

-(Tire *)tireAtIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in tireAtIndex:",index);
        exit(1);
    }
    return (tires[index]);

}

-(void)setTire:(Tire *)tire atIndex:(int)index
{
    if(index < 0 || index > 3)
    {
        NSLog(@"bad index (%d) in setTire:atIndex:",index);
        exit(1);
    }
    tires[index] = tire;
}


-(void)print
{
    NSLog(@"%@",engine);
    NSLog(@"%@",tires[0]);
    NSLog(@"%@",tires[1]);
    NSLog(@"%@",tires[2]);
    NSLog(@"%@",tires[3]);
}

@end

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

    Car *car = [Car new];
    //通过属性来设置Car对象里的成员,而不需要发送setter消息来设置(即不需要显示调用setter方法),而且这里我们使用了点运算符
    car.engine = [Engine new];
    for(int i = 0;i < 4;i++)
    {
        Tire *tire = [Tire new];
        [car setTire:tire atIndex:i];
    }
    [car print];
    return 0;
}

以上代码中还巧妙的使用了点表达式,点表达式可以用来设置和访问对象的属性。上述几个程序运行的结果都一样,读者可以试着编译运行一下,博主编译后运行结果截图如下:
这里写图片描述
最后,谢谢各位读者的浏览。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值