@property vs只是声明getter和setter

时间:2013-09-03 21:26:34

标签: objective-c

此代码之间的行为是否存在任何差异 - 无论是在编译时还是在运行时......

// 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来区分属性的声明?还有其他我没有想到的差异吗?

3 个答案:

答案 0 :(得分:6)

简短回答: 没有区别。但是,某些属性属性(copyatomic)可能需要不同的访问方法。

长答案:有一组内省函数允许您访问为给定类或协议声明的所有@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将不会包含保留/释放消息。