我认为我一直在错误地使用Objective-C属性。具体来说,我一直把它们视为实例变量。
以下是最近界面的示例:
// AIClass.h
#import "AIDataUtils.h"
@interface AIViewController : UIViewController
@property (strong, nonatomic) AIDataUtils *dataUtils;
@end
然后,在我的实现中,我会使用self.dataUtils
作为类中任何方法轻松访问相同内容的方法。来自外部的任何物体都不会与该财产互动。
我所意识到的是,我应该所做的是在实现中导入和声明AIDataUtils
而不是界面。我想那会是这样的:
// AIClass.m
#import "AIDataUtils.h"
@interface AIViewController ()
{
AIDataUtils *dataUtils;
}
@end
@implementation AIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dataUtils = [[AIDataUtils alloc] init];
...
}
The docs说:
避免显式声明公共实例变量。开发人员应该关注对象的界面,而不是关于如何存储数据的细节。
我的理解是,如果另一个对象没有触及AIDataUtils
的业务,请不要将其放在界面中。接口中存在属性这一事实应该是一个提示,您应该使用该属性提供或执行某些操作。
我是热还是冷?
答案 0 :(得分:2)
我的理解是,如果另一个对象没有触及AIDataUtils的业务,请不要将其放在界面中。
你是对的,但这并不意味着你也不能继续使用内部值的属性 - 只是不要在你的公共接口中声明它们。通常,如您所建议的那样使用类扩展是一种很好的方式来获取您的属性,同时仍然保持内部事物(或多或少)的私密性。
在Objective-C的演变过程中有一段时间,当属性对管理内存非常有帮助时 - 如果你在任何地方都使用了属性的访问器,你可能会更加担心何时保留以及何时释放某些东西,因为访问者会为你做那件事。既然我们已经拥有了ARC,那么属性的内存管理方面就不那么重要了,但是我们很多人仍然习惯使用属性甚至是内部资源。如果不出意外,仅内部属性可以使您的代码看起来更加一致。
答案 1 :(得分:1)
如果您希望dataUtils
成为私人实施细节,那么您不应该在头文件的@interface
中声明它。
即使您想将其保密,您仍然可以将其设为.m
文件中的属性:
@interface AIViewController ()
@property (strong, nonatomic) AIDataUtils *dataUtils;
@end
是将它作为属性还是仅仅是实例变量是一个品味问题,取决于你如何使用它。例如,如果您只想懒惰地分配AIDataUtils
实例,那么您也可以将其作为属性并在getter中进行延迟分配。
如果您决定将其设为实例变量,则可能没有理由在类扩展中声明它。您可以在@implementation
:
@implementation AIViewController {
AIDataUtils *dataUtils;
}
- (void)viewDidLoad {
[super viewDidLoad];
dataUtils = [[AIDataUtils alloc] init];
...
您可以详细了解如何声明实例变量in this answer。