此代码之间的行为是否存在任何差异 - 无论是在编译时还是在运行时......
// MyClass.h
@interface MyClass : NSObject
@property (nonatomic) SomeType myProperty;
@end
// MyClass.m
@implementation MyClass
@end
......还有这段代码?
// MyClass.h
@interface MyClass : NSObject
-(SomeType)myProperty;
-(void)setMyProperty:(SomeType)myProperty;
@end
// MyClass.m
@implementation MyClass {
SomeType _myProperty;
}
-(SomeType)myProperty {
return _myProperty;
}
-(void)setMyProperty:(SomeType)myProperty {
_myProperty = myProperty;
}
@end
显然,前一版本更简洁,更易读,但行为有什么不同吗?合成的getter和setter是否做了比我直接实现更复杂的事情?内省函数是否可以通过声明getter和setter来区分属性的声明?还有其他我没有想到的差异吗?
答案 0 :(得分:6)
简短回答: 没有区别。但是,某些属性属性(copy
或atomic
)可能需要不同的访问方法。
长答案:有一组内省函数允许您访问为给定类或协议声明的所有@properties
:
class_getProperty
class_copyPropertyList
protocol_getProperty
protocol_copyPropertyList
property_getName
property_getAttributes
我认为这些函数中的任何一个都不适用于生产代码,因为这基本上是类的实现细节。此外,可能在公共接口中公开了getter / setter,在类扩展中隐藏了私有属性。
哦,还有另外一个区别:Xcode突出显示属性和普通的getter:)
答案 1 :(得分:1)
一个区别是内存管理。您可以配置属性,例如复制正在设置的对象或使用弱变量。您的代码似乎假设ARC处于活动状态,因为您没有释放旧对象并保留新对象。
在ARC之前,典型的setter会像
那样-(void)setMyProperty:(SomeType *)myProperty {
if (myProperty == _myProperty) return;
[_myProperty release];
_myProperty = myProperty;
[_myProperty retain];
}
答案 2 :(得分:0)
当您说使用 ARC 时,只会有一点不同。但重要的是没有。
你的ivar是@protected。 @property创建了一个名为@private的ivar。
一般来说: 因此,当您进行子类化时,您的子类可以直接访问您创建的ivar,但不能访问属性创建的ivar。
但是,因为你将你的ivar放在@implementation块中,所以子类永远不会看到ivar。
没有ARC 但是SomeType不是Objective-C对象,因此存在很大差异。然后你的setter / getter将不会包含保留/释放消息。