iOS 成员变量与属性的区别

#import <Foundation/Foundation.h>


@interface Person : NSObject

{

    // 1.声明成员变量

    NSString *name;

    NSInteger age;

    

}

//@property声明属性

@property (nonatomic, copy) NSString *fatherName;


@end


声明的属性默认会生成一个_类型的成员变量,同时也会生成setter/getter方法。但这只是在iOS5之后,苹果推出的一个新机制。看老代码时,经常看到一个大括号里面定义了成员变量,同时用了@property声明,而且还在@implementation中使用@synthesize方法。现在编译器会自动的生成一个实例变量_fatherName,那么在.m文件中可以直接的使用_fatherName实例变量,也可以通过属性self.fatherName.都是一样的。注意这里的self.fatherName其实是调用的fatherName属性的getter/setter方法。


其实,发生这种状况根本原因是苹果将默认编译器从GCC转换为LLVM(low level virtual machine),才不再需要为属性声明实例变量了。在没有更改之前,属性的正常写法需要成员变量+ @property + @synthesize 成员变量三个步骤。


@synthesize 还有一个作用,可以指定与属性对应的实例变量,例如@synthesize fatherName = xxx;那么self.fatherName其实是操作的实例变量xxx,而不是_fatherName了。


 在实际的项目中,我们一般这么写.m文件


@synthesize fatherName;

  这样写了之后,那么编译器会自动生成fatherName的实例变量,以及相应的gettersetter方法。注意:_fatherName这个实例变量是不存在的,因为自动生成的实例变量为fatherName而不是_fatherName,所以现在@synthesize的作用就相当于指定实例变量;


  如果.m文件中写了@synthesize fatherName;那么生成的实例变量就是fatherName;如果没写@synthesize fatherName;那么生成的实例变量就是_fatherName。所以跟以前的用法还是有点细微的区别。


1.成员变量的作用范围:

@public:在任何地方都能直接访问对象的成员变量

@private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法

@protected:可以在当前类及其子类对象方法中直接访问(系统默认下是用它来修饰的)

@package:在同一个包下就可以直接访问,比如说在同一个框架


2.注意:

无论父类是在@interface还是@implementation声明的成员变量子类都能拥有;但是子类能不能直接通过变量名来访问父类中定义的成员变量是需要看父类中定义的成员变量是由什么修饰符来修饰的。


3.默认:

.m中成员变量的修饰符为@private.

.h中成员变量的修饰符@protected.


@property声明属性是: .m中成员变量的修饰符为@private. .h中成员变量的修饰符@protected.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值