4

由于 cocoa 设计模式,实例方法的名称countNSMutableArray模棱两可的;它可以返回一个保存的变量count,也可以在每次调用它时计算数组中的项目,然后返回(可可规定一个简单地返回变量值的方法foofoo,而不是getFoo)。每次调用它的方法时, Objective C 是否真的计算项目,或者它是否返回预先计算的变量的值?NSMutableArraycount如果这是 Java,我会查看源代码,但我找不到NSMutableArray. 我查看了 API,它所说的只是:

返回当前在数组中的对象数。

由于没有上下文,我无法判断这是否意味着它在其中进行任何计算。

4

2 回答 2

7

正如您正确指出的那样,不能保证它会以一种或另一种方式运行。

但实际上,它-[NSArray count]是一个恒定时间操作。您可以自己确认这一点,方法是创建一个小数组和一个大数组,并对获取它们的计数所需的时间进行基准测试。count像这样在核心数组类上使用 O(n) 方法是非常愚蠢的。

于 2013-01-31T23:50:01.797 回答
5

NSArray声明了一个私有 ivar _used,它似乎保存了数组的计数。使用object_getInstanceVariable()您可以验证在具体子类的情况下__NSArrayM,此变量会随着对象的添加和删除而递增和递减。

我使用以下程序(Mac OS X Foundation 命令行工具)来验证这一点:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        NSMutableArray *anArray = [NSMutableArray array];
        NSLog(@"anArray's concrete class is %@", [anArray class]);
        UInt64 used = 0;
        for (NSString *toAdd in @[@"o", @"m", @"g"]) {
            object_getInstanceVariable(anArray, "_used", (void **)&used);
            NSLog(@"array = %@, used = %lld", anArray, used);
            [anArray addObject:toAdd];
        }
        for (NSString *toRemove in [anArray copy]) {
            object_getInstanceVariable(anArray, "_used", (void **)&used);
            NSLog(@"array = %@, used = %lld", anArray, used);
            [anArray removeObject:toRemove];
        }
        object_getInstanceVariable(anArray, "_used", (void **)&used);
        NSLog(@"array = %@, used = %lld", anArray, used);
    }
    return 0;
}

该程序产生以下输出:

2013-01-31 17:40:15.376 Array[10173:303] anArray's concrete class is __NSArrayM
2013-01-31 17:40:15.378 Array[10173:303] array = (
), used = 0
2013-01-31 17:40:15.378 Array[10173:303] array = (
    o
), used = 1
2013-01-31 17:40:15.379 Array[10173:303] array = (
    o,
    m
), used = 2
2013-01-31 17:40:15.379 Array[10173:303] array = (
    o,
    m,
    g
), used = 3
2013-01-31 17:40:15.380 Array[10173:303] array = (
    m,
    g
), used = 2
2013-01-31 17:40:15.380 Array[10173:303] array = (
    g
), used = 1
2013-01-31 17:40:15.380 Array[10173:303] array = (
), used = 0
于 2013-02-01T00:43:22.893 回答