【发布时间】:2012-10-12 20:36:12
【问题描述】:
如何在NSFastEnumerationState 的额外数组中安全地存储几个对象实例?
我希望在循环运行时保留这些项目,然后在循环完成时释放。
- (NSUInteger)countByEnumeratingWithState: (NSFastEnumerationState *)state
objects: (__unsafe_unretained id *)stackbuf
count: (NSUInteger)len {
unsigned long days = 0;
id current = nil;
id components = nil;
if (state->state == 0)
{
current = [NSCalendar currentCalendar];
state->mutationsPtr = &state->extra[0];
components = [current components: NSDayCalendarUnit fromDate: _startDate toDate: _endDate options: 0];
days = [components day];
state->extra[0] = days;
state->extra[1] = (uintptr_t)(__bridge void *)current;
state->extra[2] = (uintptr_t)(__bridge void *)components;
} else {
days = state->extra[0];
current = (__bridge NSCalendar *)(void *)(state->extra[1]);
components = (__bridge NSDateComponents *)(void *)(state->extra[2]);
}
NSUInteger count = 0;
if (state->state <= days) {
state->itemsPtr = stackbuf;
while ( (state->state <= days) && (count < len) ) {
[components setDay: state->state];
stackbuf[count] = [current dateByAddingComponents: components toDate: _startDate options: 0];
state->state++;
count++;
}
}
return count;
}
这是NSFastEnumerationState 的定义,来自 Apple 的标题:
typedef struct {
unsigned long state;
id __unsafe_unretained *itemsPtr;
unsigned long *mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
【问题讨论】:
-
我会感到惊讶,因为这些元素默认情况下是长的。将它们类型转换为指针似乎已经是相当冒险了——希望分配给它们的任何对象都将被保留,如果没有进一步的机制似乎是不可能的。有趣的问题,因此 +1 :D
-
是的,我的 AR 转换(昨天完成)很天真,我假设我必须添加自己的机制。我希望有人比我更了解这一点。:)
-
我已经添加了
NSFastEnumerationState的定义。 -
你可以做
state->extra[1] = (uintptr_t)(__bridge_retained __strong void *)current;。但根据clang.llvm.org/docs/…,这被认为是糟糕的形式。不过,总的来说,不幸的是,这几乎是 ARC 无法做到的。 -
我不太担心它是不好的形式,因为这真的很原始。只要可以在循环完成后进行清理——我不认为是这样。 :)
标签: ios automatic-ref-counting fast-enumeration