类属性何时需要?例如:
self.MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)
VS
MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)
MyProperty是一个NSString设置为(非原子,副本).上述两种内存管理有什么不同吗?
什么时候没有属性,并且在头文件中声明了变量MyProperty?如果从未在类之外引用,是否需要属性?它对内存管理有所影响吗?
是的,内存和性能都有所不同.
MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)
这被认为是直接分配.实际上没有内存或性能影响.当然,这并不是说这是最佳实践 - 这是一个不同的问题:)
@property(nonatomic, copy) NSString *MyProperty;
// ...
self.MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)
此声明对内存和性能有重大影响.这基本上相当于:
-(void)setMyProperty(NSString *)newValue {
if (MyProperty != newValue) {
[MyProperty release];
MyProperty = [newValue copy];
}
}
Run Code Online (Sandbox Code Playgroud)
旧值将被释放,新值将复制到MyProperty中.这是可以接受的,尤其是当你的分配字符串可变时处理字符串时(例如,它可能会在以后更改).
如果在你的例子中,你只是简单地指定一个静态字符串(@"hi there"),那么直接分配字符串值没有错; 它的效率更高,但性能上的差异是微不足道的.
您可以将@property的属性声明为retain,copy或assign(默认为assign).然后,您可以使用@synthesize生成"访问者"(getter/setter)方法.以下是执行此操作时生成的setter方法的外观:
// @property(nonatomic, assign)
-(void)setMyProperty(NSString *)newValue {
MyProperty = newValue;
}
// @property(nonatomic, retain)
-(void)setMyProperty(NSString *)newValue {
if (property != newValue) {
[property release];
property = [newValue retain];
}
// @property(nonatomic, copy)
-(void)setMyProperty(NSString *)newValue {
if (property != newValue) {
[property release];
property = [newValue copy];
}
}
Run Code Online (Sandbox Code Playgroud)
有关ObjectiveC声明的属性的更多信息.
"您可以在@implementation块中使用@synthesize和@dynamic指令来触发特定的编译器操作.请注意,任何给定的@property声明都不需要.
要点:如果没有为特定属性指定@synthesize或@dynamic,则必须为该属性提供getter和setter(或者只是readonly属性的getter)方法实现."
换句话说,如果声明属性但不合成属性,除非定义"MyProperty"和"setMyProperty"方法,否则将无法使用[self MyProperty]或self.MyProperty.如果您没有声明属性,那么您只需要一个实例变量.
注意:@dynamic不会生成访问者.如果你通过加载代码或动态方法解析动态地(即,神奇地)解析访问器方法,它就真的被使用了.
不同之处在于
self.MyProperty = @"hi there"
Run Code Online (Sandbox Code Playgroud)
是点符号调用,它将调用生成的访问器,它将正确处理保留计数(相当于[self setMyProperty:@"hi there"]),而
MyProperty = @"hi there"
Run Code Online (Sandbox Code Playgroud)
是对您的成员变量的直接赋值,它不会释放旧值,保留新值或执行您的访问者所做的任何其他操作(例如,如果您有自定义setter执行额外工作).
所以,是的,内存管理和两者之间的行为存在很大差异.后一种形式几乎总是错误的,除非您明确知道为什么要这样做并且您自己正确处理保留计数.
| 归档时间: |
|
| 查看次数: |
2601 次 |
| 最近记录: |