在Objective-C中延迟初始化抽象属性的正确方法是什么

izk*_*izk 1 objective-c superclass lazy-initialization

超级课程:

@property (strong, nonatomic) Foo *foo;
Run Code Online (Sandbox Code Playgroud)

在子类中:

- (Foo *) foo
{
     if(!super.foo) super.foo = [[Foo alloc] init];
     return super.foo;
}
Run Code Online (Sandbox Code Playgroud)

这有意义吗?拥有抽象属性甚至是个好主意?

Mar*_*n R 6

严格地说,Objective-C中没有"抽象类"或"抽象属性",例如,请参阅此线程在Objective-C中创建抽象类以获得良好的概述.

你的做法是不是最佳的,因为它需要的父类实现了foosetFoo:,这与"抽象"的想法.

更好的解决方案是在超类中定义"动态属性":

@interface SuperClass : NSObject
@property (strong, nonatomic) Foo *foo;
@end

@implementation SuperClass
@dynamic foo;
@end
Run Code Online (Sandbox Code Playgroud)

并在子类中明确地合成它:

@interface SubClass : SuperClass
@end

@implementation SubClass
@synthesize foo = _foo;
@end
Run Code Online (Sandbox Code Playgroud)

现在您可以访问foo子类对象,但是在超类对象上它将导致运行时异常.

对于延迟初始化,您可以使用通常的模式,没有任何"超级技巧":

- (Foo *) foo
{
    if(!_foo) _foo = [[Foo alloc] init];
    return _foo;
}
Run Code Online (Sandbox Code Playgroud)

一种方法(在上面的线程中也提到)是使用"协议"而不是通用的超类:

@protocol HasFoo <NSObject>
- (Foo *)foo;
@end

@interface MyClass : NSObject<HasFoo>
@property(strong, nonatomic) Foo *foo;
@end

@implementation SubClass
- (Foo *) foo
{
    if(!_foo) _foo = [[Foo alloc] init];
    return _foo;
}
@end
Run Code Online (Sandbox Code Playgroud)