【问题标题】:How to safely store objects in extra within countByEnumeratingWithState under ARC?如何在 ARC 下的 countByEnumeratingWithState 中安全地存储额外的对象?
【发布时间】: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-&gt;extra[1] = (uintptr_t)(__bridge_retained __strong void *)current;。但根据clang.llvm.org/docs/…,这被认为是糟糕的形式。不过,总的来说,不幸的是,这几乎是 ARC 无法做到的。
  • 我不太担心它是不好的形式,因为这真的很原始。只要可以在循环完成后进行清理——我不认为是这样。 :)

标签: ios automatic-ref-counting fast-enumeration


【解决方案1】:

史蒂文,

您为什么要尝试使用 C 语言结构来保存这些项目,而不是在您正在为其构建枚举器的类中将它们设为私有 ivars?让它们成为 ivars,问题就不存在了。

安德鲁

【讨论】:

  • 这在这里可以工作,因为它们是常量,但是如果变量作为循环的一部分而变化,则循环不是可重入的。 :)
猜你喜欢
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多