2

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

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

4

3 回答 3

6

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

长答案:有一组自省函数允许您访问@properties为给定类或协议声明的所有内容:

class_getProperty
class_copyPropertyList
protocol_getProperty
protocol_copyPropertyList
property_getName
property_getAttributes

我认为这些函数中的任何一个在生产代码中都没有用,因为这基本上是类的实现细节。此外,可能有一个 getter/setter 暴露在公共接口中,一个私有属性隐藏在类扩展中。

哦,还有另一个区别:Xcode 以不同的方式突出显示属性和普通 getter :)

于 2013-09-03T21:34:17.077 回答
1

一个区别是内存管理。您可以将属性配置为例如复制正在设置的对象或使用弱变量。您的代码似乎假设 ARC 处于活动状态,因为您没有释放旧对象并保留新对象。

在 ARC 之前,典型的二传手会像

-(void)setMyProperty:(SomeType *)myProperty {
    if (myProperty == _myProperty) return;
    [_myProperty release];
    _myProperty = myProperty;
    [_myProperty retain];
}
于 2013-09-03T21:35:49.527 回答
0

当您说您使用ARC时,只有很小的区别。但这些都不重要。

你的 ivar 是@protected。@property 创建一个 ivar,它是 @private。

一般来说:因此,当您进行子类化时,您的子类可以直接访问您创建的 ivar,但不能访问属性创建的那个。

但是由于您将 ivar 放在 @implementation 块中,因此子类永远不会看到 ivar。


然而,如果没有 ARC并且 SomeType 不是一个 Objective-C 对象,就会有很大的不同。那么你的 setter/getter 就不会包含保留/释放消息。

于 2013-09-04T08:40:15.560 回答