方式一:(为何要定义一个_test?下划线开头代表什么意思?在实现的时候怎么又将_test付给了test?) 方式二:(方式2跟方式1到底有何区别?) 方式三:(这种最简单了,但是这样写规范吗?) 这个成员变量定义这块儿,整的很乱,看了很多教程,一个教程一个写法,有时候教程前后还不一样。我更迷茫了,到底该如何定义成员变量?求详细解答。谢谢了。
闭关修行中......
第二第三种个人感觉是极不规范的。
第一种是比较老式的写法,不过 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 中,都是私有了。
尽量的使用属性而非实例变量。除了在初始化方法(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
良好的风格:
不要使用@synthesize除非是编译器需要。注意在@protoco协议中的@optional可选属性必须被显式地使用@synthesize指令合成属性。
参考:iOS应用开发最佳实践系列一:编写高质量的Objective-C代码
第三种,但不全是你那样,应该是:
#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 propertyName 给 ivarName 变量,通过:
ivarName
propertyName
@synthesize propertyName = ivarName;
关于使用下划线。 在实例变量前使用下划线这是共同约定的常用写法,当实例方法参数和实例变量重名时,这样做可以防止名字冲突,或者编译器警告。 下划线前缀也可明确指出你正在引用一个ivar。 通过为实例变量使用下划线前缀,你可以在方法参数,堆栈变量等地方自由地使用不带下划线的名称。 但是当你使用 property 时,一般你不会想让用户去写一个下划线,因此你通常会为一个叫做 _ivarName 实例变量取一个叫做 ivarName 的 property。 这就是为什么你要写成:
_ivarName
@synthesize ivarName = _ivarName;
synthesize可以是用来定义属性,他会自动生产get/set。 个人觉得: * 如果定义的是外部可见的属性,我觉得应该采用最简单的方式三,理由是简洁。 * 如果是定义内部属性或变量,建议放到 .m活.mm文件中定义,以体现对外隐藏意思(当然不能真正隐藏)。 * 如果是值语义的内部变量,用synthesize不但没什么好处,还会增加运行时开销。
最新的Xcode中 直接定义@property 就行,不用@synthesize。编译时编译系统会自动帮你加上。
@interface Test () @property (nonatomic, copy) NSString *test; @end
property 建议加下划线。instance variable 不加。
@interface RNCSection: NSObject
@property (nonatomic) NSString *headline;
@end
直接这样最好,会自动生成getter setter方法
同问,我也比较晕。
用Swift吧 然后就不用纠结了
如果是.m实现中的私有变量只想别人get,不想别人set如何写呢?
第二第三种个人感觉是极不规范的。
第一种是比较老式的写法,不过 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 中,都是私有了。
尽量的使用属性而非实例变量。除了在初始化方法(init,initWithCoder:等)、dealloc方法以及自定义setter与getter方法中访问属性合成的实例变量,其他的情况使用属性进行访问。
良好的风格:
不良的风格:
当你使用@synthesize指令时,编译器会自动为你创建一个下划线_开头的的实例变量,所以不需要同时声明实例变量和属性。
不良的风格:
良好的风格:
不要使用@synthesize除非是编译器需要。注意在@protoco协议中的@optional可选属性必须被显式地使用@synthesize指令合成属性。
参考:iOS应用开发最佳实践系列一:编写高质量的Objective-C代码
规范
第三种,但不全是你那样,应该是:
关于为什么要用下划线
一个 Objective-C property 通常会有一个辅助 ivar。
property 可能会有一个不同于 ivar 的名字。
对于实例,你可能会有一个叫做
ivarName
的 ivar,和一个叫做propertyName
的 property。你可以 synthesize
propertyName
给ivarName
变量,通过:关于使用下划线。
在实例变量前使用下划线这是共同约定的常用写法,当实例方法参数和实例变量重名时,这样做可以防止名字冲突,或者编译器警告。
下划线前缀也可明确指出你正在引用一个ivar。
通过为实例变量使用下划线前缀,你可以在方法参数,堆栈变量等地方自由地使用不带下划线的名称。
但是当你使用 property 时,一般你不会想让用户去写一个下划线,因此你通常会为一个叫做
_ivarName
实例变量取一个叫做ivarName
的 property。这就是为什么你要写成:
synthesize可以是用来定义属性,他会自动生产get/set。
个人觉得:
* 如果定义的是外部可见的属性,我觉得应该采用最简单的方式三,理由是简洁。
* 如果是定义内部属性或变量,建议放到 .m活.mm文件中定义,以体现对外隐藏意思(当然不能真正隐藏)。
* 如果是值语义的内部变量,用synthesize不但没什么好处,还会增加运行时开销。
最新的Xcode中 直接定义@property 就行,不用@synthesize。编译时编译系统会自动帮你加上。
property 建议加下划线。instance variable 不加。
@interface RNCSection: NSObject
@property (nonatomic) NSString *headline;
@end
直接这样最好,会自动生成getter setter方法
同问,我也比较晕。
用Swift吧 然后就不用纠结了
如果是.m实现中的私有变量只想别人get,不想别人set如何写呢?