ios - Objective-c成员变量的定义方式?如何写才规范?
阿神
阿神 2017-04-17 13:13:12
0
9
347

方式一:(为何要定义一个_test?下划线开头代表什么意思?在实现的时候怎么又将_test付给了test?)

方式二:(方式2跟方式1到底有何区别?)

方式三:(这种最简单了,但是这样写规范吗?)

这个成员变量定义这块儿,整的很乱,看了很多教程,一个教程一个写法,有时候教程前后还不一样。我更迷茫了,到底该如何定义成员变量?求详细解答。谢谢了。​​​

阿神
阿神

闭关修行中......

répondre à tous(9)
阿神

第二第三种个人感觉是极不规范的。

第一种是比较老式的写法,不过 NSString *_test; 这个就是多余的了,这个是更老式的了,那时候要手写 getter setter
因为有了 synthesize 自动属性合成器以后,这步,Xcode已经帮你做过了。
还帮你写了默认的 getter setter 方法,有下划线就是标识,这个是成元变量,以便于区分 getter setter 中的形参(局部变量)。

在 m 文件中是可以直接对 带下划线的 成员变量进行赋值等操作的,但规范还是建议 使用 self.test 这样来操作,除非你正在 setter getter 方法中,那是不能用这个。

还有谷歌那个 objc 代码风格,, 哈哈成员变量 下划线在后面, test_ ,又晕了吧?我估计这个风格是为了完全区分 纯成员变量,和 属性。就是说 后面带下划线的这货,就纯粹是类本身自己用,没有 getter setter,不需要给别的类访问。

最后,早在 Xcode 4.6 起,还是更早来着,记不得了, 什么 synthesize 根本不用写的,Xcode 已经帮你写了 @synthesize test = _test。

所以现在最简洁的思路就是,如果你这个变量,是要给其他类能够访问到的,那么你就直接写个 @property 就够了。

声明成员变量 NSString *_test; 还有属性合成器 @synthesize test = _test,不需要写了,

如果你这个变量,完全不需要给类外部访问,那么你就 自己声明个 成员变量 NSString *test_; 其他别写。该初始化的地方初始化该释放的释放

//----------------

发现被踩了下,纯个人理解可能会有误,如有误望不吝请指出,多谢,

前面最后说的有些不严谨了~ 没说 在 h 和 m 中的区别。
在 h 中,只有 成员变量的话虽然没有 getter setter , 子类还是能访问的。属性的话就是相当于公开的。

在 m 中,都是私有了。

Peter_Zhu

尽量的使用属性而非实例变量。除了在初始化方法(init,initWithCoder:等)、dealloc方法以及自定义setter与getter方法中访问属性合成的实例变量,其他的情况使用属性进行访问。

良好的风格:

@interface RNCSection: NSObject

@property (nonatomic) NSString *headline;

@end

不良的风格:

@interface RNCSection : NSObject {

NSString *headline;

}

当你使用@synthesize指令时,编译器会自动为你创建一个下划线_开头的的实例变量,所以不需要同时声明实例变量和属性。

不良的风格:

@interface RNCSection : NSObject {
NSString *headline;
}
@property (nonatomic) NSString *headline;
@end

良好的风格:

@interface RNCSection: NSObject

@property (nonatomic) NSString *headline;

@end

不要使用@synthesize除非是编译器需要。注意在@protoco协议中的@optional可选属性必须被显式地使用@synthesize指令合成属性。

参考:iOS应用开发最佳实践系列一:编写高质量的Objective-C代码

Peter_Zhu

规范

第三种,但不全是你那样,应该是:

#import "Test.h"

@interface Test ()  
@property (nonatomic, copy) NSString *test;
@end

@implementation Test
@synthesize test = _test;
@end 

关于为什么要用下划线

一个 Objective-C property 通常会有一个辅助 ivar。
property 可能会有一个不同于 ivar 的名字。
对于实例,你可能会有一个叫做 ivarName 的 ivar,和一个叫做 propertyName 的 property。
你可以 synthesize propertyNameivarName 变量,通过:

@synthesize propertyName = ivarName;

关于使用下划线。
在实例变量前使用下划线这是共同约定的常用写法,当实例方法参数和实例变量重名时,这样做可以防止名字冲突,或者编译器警告。
下划线前缀也可明确指出你正在引用一个ivar。
通过为实例变量使用下划线前缀,你可以在方法参数,堆栈变量等地方自由地使用不带下划线的名称。
但是当你使用 property 时,一般你不会想让用户去写一个下划线,因此你通常会为一个叫做 _ivarName 实例变量取一个叫做 ivarName 的 property。
这就是为什么你要写成:

@synthesize ivarName = _ivarName;
Ty80

synthesize可以是用来定义属性,他会自动生产get/set。
个人觉得:
* 如果定义的是外部可见的属性,我觉得应该采用最简单的方式三,理由是简洁。
* 如果是定义内部属性或变量,建议放到 .m活.mm文件中定义,以体现对外隐藏意思(当然不能真正隐藏)。
* 如果是值语义的内部变量,用synthesize不但没什么好处,还会增加运行时开销。

大家讲道理

最新的Xcode中 直接定义@property 就行,不用@synthesize。编译时编译系统会自动帮你加上。

@interface Test ()  
@property (nonatomic, copy) NSString *test; 
@end 

property 建议加下划线。instance variable 不加。

Peter_Zhu

@interface RNCSection: NSObject

@property (nonatomic) NSString *headline;

@end

直接这样最好,会自动生成getter setter方法

洪涛

同问,我也比较晕。

洪涛

用Swift吧 然后就不用纠结了

Peter_Zhu

如果是.m实现中的私有变量只想别人get,不想别人set如何写呢?

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal