一尘不染

Swift中的惰性属性初始化

swift

您将如何在Swift中实现以下模式?

所述Container类被初始化,其中包含的词典JSON数组。这些字典用于初始化Entry类。但是,Entry当访问entriessearchEntries属性时,对象的初始化会延迟进行。

@interface Container

@property (readonly, nonatomic) NSArray *entryDicts;

@property (readonly, nonatomic) NSArray* entries;
@property (readonly, nonatomic) NSDictionary *searchEntries;

@end



@implementation Container

- (instancetype)initWithArray:(NSArray *)array
{
    self = [super init];
    if (self) {
        _entryDicts = array;
    }
    return self;
}

@synthesize entries = _entries;
- (NSArray *)entries
{
    [self loadEntriesIfNeeded];
    return _entries;
}

@synthesize entriesByNumber = _entriesByNumber;
- (NSDictionary *)entriesByNumber
{
    [self loadEntriesIfNeeded];
    return _entriesByNumber;
}

- (void)loadEntriesIfNeeded
{
    if (_entries == nil) {
        // Load entries
        NSMutableArray *entries = [NSMutableArray arrayWithCapacity:[self.entriesDict count]];
        NSMutableDictionary *entriesByNumber = [NSMutableDictionary dictionaryWithCapacity:[self.entriesDict count]];

        [self.entriesDict enumerateKeysAndObjectsUsingBlock:^(NSString *number, NSDictionary *entryDict, BOOL *stop) {
            Entry *entry = [[Entry alloc] initWithDictionary:entryDict container:self];
            [entries addObject:entry];
            entriesByNumber[number] = entry;
        }];

        _entries = [entries copy];
        _entriesByNumber = [entriesByNumber copy];

        // Delete dictionaries
        _entriesDict = nil;
    }
}

@end

阅读 276

收藏
2020-07-07

共1个答案

一尘不染

看来这个问题已经得到了很大的回答,但是回过头来看原始帖子,这是(IMHO)Swift中相对简洁的翻译。关键是您可以链接惰性属性。请注意,我同时使用了类函数和闭包-
两者都很好。

import Swift

println("begin")

class ClassWithLazyProperties {

    lazy var entries:[String] = ClassWithLazyProperties.loadStuff()
    lazy var entriesByNumber:Dictionary<Int, String> = {

        var d = Dictionary<Int, String>()
        for i in 0..<self.entries.count {
            d[i] = self.entries[i]
        }
        return d
    }()

    private class func loadStuff() -> [String] {
        return ["Acai", "Apples", "Apricots", "Avocado", "Ackee", "Bananas", "Bilberries"]
    }

}

let c = ClassWithLazyProperties()
c.entriesByNumber
    // 0: "Acai", 1: "Apples", 2: "Apricots", 3: "Avocado", 4: "Ackee", 5: "Bananas", 6: "Bilberries"]


println("end")
2020-07-07