Классный вопрос!
Вы могли бы реализовать ленивый контейнер в Objective-C следующим образом (но, вероятно, не стоит, см. Ниже):
typedef id (^SuspBlock)(void);
@interface Susp : NSObjecti
- (id)initWithBlock:(SuspBlock)block;
+ (id)withBlock:(SuspBlock)block;
- (id)force;
@end
// -----
@interface Susp ()
@property (nonatomic, copy) SuspBlock _block;
@end
@implementation Susp
@synthesize _block;
- (id)initWithBlock:(SuspBlock)block {
self = [super init];
if (self != nil) {
self._block = block;
}
return self
}
+ (id)withBlock:(SuspBlock)block {
return [[[self alloc] initWithBlock:bloc] autorelease];
}
- (id)force {
return self._block();
}
- (void)dealloc {
self._block = nil;
[super dealloc];
}
@end
Это много шаблонного, но что угодно.Затем вы можете использовать это так:
id x = [Susp withBlock:^{ return someComputation(); }];
id result = [[x force] plus:[x force]];
// assuming the result of your computation has -plus:
Но это все довольно глупо, поскольку для того, что вы делаете, вам действительно не нужен другой тип данных.Просто используйте блоки в качестве вашего типа данных:
typedef id (^SuspVal)(void);
SuspVal x = ^{ return complicatedThing; };
id result = [x() plus:x()];
Это гораздо более компактный идиоматичный способ решения этой проблемы, и я предлагаю это.Если вам не нужно добавлять в свои ленивые объекты дополнительную семантику, выходящую за рамки базовых утилит блоков, вам не следует оборачивать их без нужды.
Приветствия!