最佳实践访问者:@property @synthetise

时间:2012-06-12 05:53:10

标签: objective-c cocoa properties accessor

我在我的应用中使用以下代码:

@interface OMNController : NSObject
{
  IBOutlet NSSearchField *filterFieldMonitor;
  OMNMonitorTableView *monitorTableView;
}


@implementation OMNController
- (id) init
{
  monitorTableView = [[OMNMonitorTableView alloc] init];
  NSString *l_filter = [filterFieldMonitor stringValue];
  [monitorTableView setFilter:l_filter];
}
  ....
@end

在这段代码1中,不需要使用@property @synthesize,它可以正常工作。

对于最佳实践,我是否必须使用accessor / ivar:

@interface OMNController : NSObject
{
  IBOutlet NSSearchField *_filterFieldMonitor;
  OMNMonitorTableView *_monitorTableView;
}
@property (readwrite, retain) OMNMonitorTableView *monitorTableView;
@property (assign) IBOutlet NSSearchField *filterFieldMonitor;;


@implementation OMNController

@synthesize monitorTableView = _monitorTableView;
@synthesize filterFieldMonitor = _filterFieldMonitor;

- (id) init
{
  self.monitorTableView = [[OMNMonitorTableView alloc] init];
  NSString *l_filter = [self.filterFieldMonitor stringValue];
  [self.monitorTableView setFilter:l_filter];
}
  ....
@end

-

@interface OMNController : NSObject
{
  IBOutlet NSSearchField *filterFieldMonitor;
  OMNMonitorTableView *monitorTableView;
}
@property (readwrite, retain) OMNMonitorTableView *monitorTableView;
@property (assign) IBOutlet NSSearchField *filterFieldMonitor;;


@implementation OMNController

@synthesize monitorTableView;
@synthesize filterFieldMonitor;

- (id) init
{
  monitorTableView = [[OMNMonitorTableView alloc] init];
  NSString *l_filter = [filterFieldMonitor stringValue];
  [monitorTableView setFilter:l_filter];
}
  ....
@end

最佳方法是什么,代码1或代码2或代码3?

2 个答案:

答案 0 :(得分:1)

首先,Cocoa社区关于是否应该在init / dealloc中调用访问器的问题存在相当大的争议。请参阅相关问题hereherehere。就个人而言,我陷入了“不要那样做”的阵营,但同样,这也是值得商榷的。

其次,使用现代运行时,您根本不需要声明ivars。只需声明您的属性,并完成它。 ivars是自动合成的。

第三,对于仅在内部使用的属性(不在其定义的类之外),根本没有理由将它们放在头文件中。您可以在实现中将它们声明为类扩展。

最后,对于可能只创建一次的对象,我已经在访问器中懒惰地创建它们,而不是在init中显式创建。

考虑到所有这些,这就是我可能会写它的方式:

// OMNController.h
@interface OMNController : NSObject
@end

// OMNController.m
@interface OMNController ()
@property (nonatomic, retain) OMNMonitorTableView *monitorTableView;
@property (nonatomic, retain) IBOutlet NSSearchField *filterFieldMonitor;
@end

@implementation OMNController

@synthesize monitorTableView = _monitorTableView;
@synthesize filterFieldMonitor = _filterFieldMonitor;

- (OMNMonitorTableView*) monitorTableView 
{
    if( !_monitorTableView ) {
        _monitorTableView = [[OMNMonitorTableView alloc] init];
        NSString *l_filter = [self.filterFieldMonitor stringValue];
        [_monitorTableView setFilter:l_filter];
    }
    return _monitorTableView;
}

@end

答案 1 :(得分:0)

我总是被教导作为“正确”OO设计的一部分,不应该直接访问对象的成员变量,而应该定义方法(或属性)来读取或操作这些变量。

如果这样,Objective-C需要付出一些努力(好玩吗?)。您使用@property@synthesize,这样您就不必明确声明您的属性和内存管理。 This回答更详细地解释了这种行为。

我还建议您查看Apple Developer Library上的Declared Properties