码迷,mamicode.com
首页 > 其他好文 > 详细

黑马程序员---Objective-C基础学习---编译器特性@property和@synthesize

时间:2015-05-10 22:17:25      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

                 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 

编译器特性@property和@synthesize

1、@property

@property可以自动生成某个成员变量的setter和getter声明。

新建一个项目,添加Person类。

Person.h

//
//  Person.h
//  zijia
//
//  Created by zou on 5/10/15.
//  Copyright (c) 2015 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
    double _height;
    
}

@property
int age; - (void)setHeight:(double)height; - (double)height; @end

当编译器遇到@property 会自动展开对应的setter和getter声明,这里@property int age会自动展开成:

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

这里可以验证一下,看一下能不能在main.m中调用set和get方法。

main.m

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

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

    @autoreleasepool {
        
        Person *p = [Person new];
        
       [p setAge : 10];
        
        int a = [p age]; // int a = [p age];
        
        NSLog(@"age is %d",a);
        
    }
    return 0;
}

有了声明还应该有实现

Person.m

#import "Person.h"

@implementation Person

- (void)setAge:(int)age
{
     _age = age;
    
}
- (int)age
{    
    return _age;
}
- (void)setHeight:(double)height
{
    _height = height;
}
- (double)height
{
    return _height;
}
@end

这里对象p调用了set和get方法,看编译能不能通过。

打印结果:

技术分享

这里证明@property确实生成了成员变量的setter和getter声明。

所以这里成员变量_height的setter和getter声明也可写成@property double height;

@property double height;
//- (void)setHeight:(double)height;
//- (double)height;
@end

二、@synthesize

@synthesize可以自动生成成员变量setter和getter实现部分,并且会访问“_成员变量”这个成员变量。

Person.m

#import "Person.h"

@implementation Person

@synthesize  age=_age;

@synthesize  height=_height;

- (void)test
{
  NSLog(@"age=%d,_age=%d",age,_age);
}
@end

@synthesize age = _age; 等号右边的_age,表示将来set方法设置的值将会赋值给成员变量_age,这里为了验证可以添加一个成员变量int age;

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
    int age;
    double _height;
    
}
@property int age;
@property double height;
- (void)test;
@end

如果在Person.m中写的是@synthesize age = age,那么set方法将来就会把值赋给成员变量age,这里可以写个test方法验证一下。

main.m

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

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

    @autoreleasepool {
        
        Person *p = [Person new];
        
       [p setAge : 10];
        [p test];

        
    }
    return 0;
}

这里编译运行一下:

技术分享

 

通过打印结果我们发现age的值没有改变,还是默认值0,而_age的值变成了10,这里我们把Person.m里面的@synthesize age=_age,写成@synthesize age=age,重新打印一下结果发现:

技术分享

age的值变成了10,而_age值为0,这说明setter方法究竟改变那个成员变量,取决于@synthesize 等号后面的变量是什么。

这里发现使用编译器特性@property和@synthesize可以避免写很多重复的代码,这里还可以更精简。

新添加一个Dog类。

Dog.h

#import <Foundation/Foundation.h>

@interface Dog : NSObject

@property int age;

@end

这里都不用写成员变量,Dog.m里面也不用写实现的代码,@property int age这行代码做了三件事情:

第一,生成getter和setter的声明;

第二,生成了一个_age的成员变量;

第三;生成了getter和setter的实现;

这里可以验证一下:

main.m

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

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

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

打印一下结果:

技术分享

这里验证了之前的说法。这里需要注意的是age默认是私有成员变量,子类是不能访问的,如果想让子类也能访问的话,需要写明成员变量。

#import <Foundation/Foundation.h>

@interface Dog : NSObject
{
    int _age;
}
@property int age;

@end

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

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

自从Xcode 4.x之后,@property功能就涵盖了@synthesize的功能,@synthesize就可以省略不写。

如果手动实现setter方法,编译器就会自动生成getter方法和带下划线的成员变量。

如果手动实现getter方法,编译器就会自动生成setter方法和带下划线的成员变量。

如果手动实现setter和getter方法,编译器就不会生成getter和setter方法,也不会生成带下划线的成员变量。

黑马程序员---Objective-C基础学习---编译器特性@property和@synthesize

标签:

原文地址:http://www.cnblogs.com/zss-itcast/p/4493068.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!