我想创建一个类作为基类(或#34; abstract")类,由子类扩展。我能解释我所说的最好的方法就是举几个例子。这是我的超类的可能接口:
#import <Cocoa/Cocoa.h>
#import "MyViewControllerDelegate.h"
@interface MyViewController : NSViewController
@property (nonatomic, weak) id<MyViewModeControllerDelegate> delegate;
@property (nonatomic, copy) NSArray *content;
@end
这样写它似乎很干净,但我无法从我的子类访问ivars。
在做了一些研究后,我得出结论,提供直接访问ivars的子类的好方法是使用@protected
指令并在头文件中包含任何声明,以便子类可以看到它:
#import <Cocoa/Cocoa.h>
#import "MyViewControllerDelegate.h"
@interface MyViewController : NSViewController {
@protected
__weak id<MyViewControllerDelegate> _delegate;
NSMutableArray *_content;
}
@property (nonatomic, weak) id<BSDViewModeControllerDelegate> delegate;
@property (nonatomic, copy) NSArray *content;
@end
我个人对此没有任何问题,它似乎按我想要的方式工作(例如,子类可以直接访问ivars,但其他类必须使用访问器)。但是,我每天都会阅读博客文章或Stack Overflow答案,说明实例变量应该只是合成,或者“我甚至不再触摸实例变量”。&#34;
问题是,我开始学习ARC后的Objective-C,所以我并不完全了解开发人员过去做事的方式。我个人喜欢我实现自己的getter / setter时的控件,我喜欢能够实际看实例变量声明,但也许我是老学校。我的意思是,如果一个人应该&#34;让编译器合成实例变量,&#34;如何包含任何类型的逻辑或副作用&#34;没有实现一堆KVO?
例如,如果合成了我的实例变量和getter / setter,我该如何懒惰地初始化东西?例如,我有时喜欢这样做:
- (NSArray *)myLazyArray
{
if ( _myLazyArray == nil ) {
self.myLazyArray = @[];
}
return _myLazyArray.copy;
}
或者如何确保设置的值与当前设置的值不相同?我有时会在我的mutator方法中执行检查,如下所示:
- (void)setMyLazyArray:(NSArray *)array
{
if ( [array isEqualToArray:_myLazyArray] )
return;
_myLazyArray = array.mutableCopy;
}
我已经阅读了Apple的所有文档,但是他们的一半文档可以追溯到2008年(或者在某些情况下更糟),所以我并不完全确定它们是最好的获取有关此事的信息。
我想我的问题的主旨是:有一个首选的&#34;现代&#34;在Objective-C中处理实例变量,变量合成,继承,范围等的方法?不包含答案的奖励积分&#34; Bro,Swift。&#34;或者&#34;你没有使用Swift?&#34;
非常感谢任何指导。谢谢你的阅读!
答案 0 :(得分:2)
为什么你的子类需要访问你的ivars? Ivars是一个实现细节,子类不应该关注它。如果父类在属性setter / getters中执行逻辑,则可能存在各种副作用。因此,请始终通过财产访问它们。
假设这是在您的子类中,并且您正在覆盖属性getter:
- (NSArray *)myLazyArray
{
if ( super.myLazyArray == nil ) {
// do what you need to do to populate the array
// assign it to yourself (or super)
self.myLazyArray = @[];
}
return super.myLazyArray;
}
然后对于二传手:
- (void)setMyLazyArray:(NSArray *)array
{
if ( [array isEqualToArray:super.myLazyArray] )
return;
super.myLazyArray = array.mutableCopy;
}