iOS中成员变量、属性变量、局部变量、全局变量

本文详细介绍了iOS开发中常见的变量类型,包括成员变量、属性变量、局部变量和全局变量,阐述了它们的定义、用途及区别,并讨论了如何合理使用这些变量以避免内存泄漏等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS中各种变量

当你一个项目历史比较悠久、团队开发人员很多的时候,代码中就有不同的编码风格的代码,团队近期在做皮肤的设置,小编承担团队皮肤的适配工作,业务涉及的页面比较多,开发人员也在不断迭代,适配不同的页面的时候发现不同页面中对于变量的定义、使用有不同的方式,小编想记录一下不同的变量的定义和使用方式;iOS中常用的有成员变量、属性变量、局部变量、全局变量

一、成员变量
@interface myViewController : UIViewController
{
    UIButton *otherButton;
    int num;
}

@property (nonatomic, strong) UIButton *loginButton;

@end
(1)成员变量

成员变量 = 基本数据类型变量 + 实例变量,在**{}**中声明的变量都是成员变量,所以otherButton和num是成员变量。

(2)实例变量

如果成员变量的数据类型是一个类,这个成员变量就是实例变量,实例是类的声明,针对类而言,上面otherButton就是实例变量,int是基础数据类型,num不是实例变量。

成员变量是定义在{}中的变量,如果变量的数据类型是一个类,则这个变量就是实例变量。成员变量用于类内部,具有私有性外界无法访问成员变量,因为成员变量不会生成set、get方法,成员变量默认是protected。

二、属性变量

property的本质 = ivar(成员变量) + getter + setter;属性变量是为了解决成员变量无法与外界交换产生的,由@propety关键字来生成,加上该关键字之后,代码在编译的时候会自动合成,生成setter、geter方法以及一个成员变量,这个实例变量默认以下划线+属性变量名称构成,如果想给该成员变量跟改名字,可以使用**@synthesize**关键字,比如

@synthesize loginButton = _newloginButton;

这样更改之后,不能在使用_loginButton来访问成员变量,应该使用__newloginButton来访问这个实例变量。

注意: 不能声明与成员变量同名的属性变量,因为成员变量不能生成setter、getter方法。

但是,如果想阻止编译器生成存取方法可以使用**@dynamic**关键字,它会告诉编译器不要创建存取方法和实例变量。

三、局部变量
-(void)viewDidLoad 
{  
    NSArray *array = [[NSArray alloc] initWithObject:@“加油”,nil];  // 局部变量
} 

局部变量的生命周期是在以“{ }”为界限的代码块中,在{}中局部变量有效,在{}外部无法使用局部变量。

四、全局变量

全局变量是在@implementation外定义的变量,例如下面全局变量的定义

static int num=3;// 全局变量 
NSString *view= @"myViewController";// 全局变量 
@implementation myViewController 
@end 
五、总结

一、 @synthesize合成成员变量的规则,有以下3点:

  1. 如果指定了名称,会生成一个指定名称的成员变量;
  2. 如果没有指定成员变量的名称,会自动生成一个属性同名的成员变量;
  3. 如果这个成员变量已经存在,就不会自动合成,例如下图

img

此时通过self._newName = @"123"进行赋值,就会出现崩溃,[ViewController set_newName:]: unrecognized selector sent to instance 0x7faeb241b2e0因为属性_newName没有自动合成,点语法又是访问setter方法,setter方法根本不存在(参考这篇文章https://www.jianshu.com/p/be14f372752b实例)

二、@synthesize和@dynamic区别

@synthesize
编译器期间,让编译器自动生成getter/setter方法。
当有自定义的存或取方法时,自定义会屏蔽自动生成该方法

@dynamic
告诉编译器,不自动生成getter/setter方法,避免编译期间产生警告
然后由自己实现存取方法
或存取方法在运行时动态创建绑定:主要使用在CoreData的实现NSManagedObject子类时使用,由Core Data框架在程序运行的时动态生成子类属性

三、访问属性有self和无self的区别,即self.loginButton和_loginButton的区别

属性的本质 = ivar(成员变量) + getter + setter,是一个整体、是外部访问的一个接口,而实例变量只能在本类中才可以访问,外部不可以访问。使用“.”语法来初始化变量的时候,会产生内存泄漏的问题:

self.loginButton = [UIButton alloc] init];

​ 上述代码,造成的问题是,在self.loginButton的时候相当于调用了set方法,引用计数+1,后面alloc的时候,引用计数再次+1。在dealloc中release时,引用计数只减了一次,未完成全部释放,这样就造成了内存泄漏的问题。

解决方法:就是用“_”来初始化以及访问变量,这样就不会产生内存问题,虽不是什么高明的办法,但的确有效。

_loginButton = [UIButton alloc] init];

上述便是“.”和“_”在使用的时候的简单区别。

但在ARC(自动管理内存)的情况下虽然不存在上述问题,但从编码规范来考虑,还是注意点儿的好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值