Apple的Cocoa文档提问

时间:2011-01-08 23:32:03

标签: objective-c cocoa

我正在慢慢地,但肯定地通过Apple的密集文档,但我真的要问一个问题。给出以下示例代码:

#import "MonthArray.h"

@implementation MonthArray

static MonthArray *sharedMonthArray = nil;
static NSString *months[] = { @"January", @"February", @"March",
    @"April", @"May", @"June", @"July", @"August", @"September",
    @"October", @"November", @"December" };

+ monthArray
{
    if (!sharedMonthArray) {
        sharedMonthArray = [[MonthArray alloc] init];
    }
    return sharedMonthArray;
}

- (unsigned)count
{
 return 12;
}

- objectAtIndex:(unsigned)index
{
    if (index >= [self count])
        [NSException raise:NSRangeException format:@"***%s: index
            (%d) beyond bounds (%d)", sel_getName(_cmd), index,
            [self count] - 1];
    else
        return months[index];
}

@end

以下是我的问题(我为没有创建多个主题而道歉,但从我所知道的内容 - 这些是非常基本的。)

  1. 显示+ monthArray时究竟是什么意思?我知道+表示它是一个类方法,但我不完全理解它有什么含义。它究竟与普通方法有什么不同?

  2. 此代码中整个sharedMonthArray ivar的目的是什么?我的意思是,objectAtIndex:方法是从几个月的字符串中拉出来的,那么重点是什么?

  3. [自我统计]方法中的“自我”是什么?我的意思是,我明白这应该是几个月,但我在哪里可以看到这个程序?什么使[自我计数]计算月份而不计算MonthArrays的数量?

  4. 对不起,如果我的问题是超级小学,我还在学习 - 提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

  

显示+ monthArray时究竟是什么意思?我知道+表示它是一个类方法,但我不完全理解它有什么含义。它究竟与普通方法有什么不同?

类方法是可以在不提供类实例的情况下调用的函数。在Objective-C中,您通常按如下方式将消息发送到实例:[someObject someMethod];使用类方法,您将消息发送到本身:[SomeClass someClassMethod];。类方法通常用于执行特定于该特定类的所有对象的操作,例如创建新实例(即工厂方法)或维护/更新全局类变量。

  

此代码中整个sharedMonthArray ivar的目的是什么?我的意思是,objectAtIndex:方法是从几个月的字符串中拉出来的,那么重点是什么?

sharedMonthArray的目的是持有该类的单个常见实例。每次调用+monthArray时都可以返回一个新实例,但这可能是浪费内存,因为实际上只需要一个。大多数Cocoa代码使用NSArray个对象,而不是简单的C风格数组,因此这个单个实例就像一个NSArray包装器,用来隐藏其余的静态C数组。该程序通过提供NSArray实例来代替。在内部,使用C样式数组是因为在编译时无法创建静态常量NSArray对象。

  

[自我统计]方法中的“自我”是什么?我的意思是,我明白这应该是几个月,但我在哪里可以看到这个程序?什么使[自我计数]计算月份而不计算MonthArrays的数量?

self是一个自动变量,Objective-C运行时用来保存接收特定消息的对象。如果您发送消息[someObject someMethod];,则会跳转到-someMethod方法,self的值将等于someObject。在此示例中,self将是MonthArray发送-objectAtIndex:消息的任何实例。调用[self count]将导致调用方法-count,并根据显示的代码返回值12.

我想补充一点,这里显示的代码在Cocoa世界中是相当独特的。你真正写这样的东西的唯一一次是你是在创建自己的框架。大多数Cocoa源代码都不会使用C风格的数组。这个特定例子的目的是什么?它绝对不是Cocoa开发人员每天编写的代码。

答案 1 :(得分:1)

此对象实现为单例,这意味着在正常使用中只有一个实例。您可以使用[MonthArray monthArray]获取对该实例的引用,该实例会将消息+monthArray发送到类MonthArray。如果需要,该方法会创建sharedMonthArray并返回它。由于sharedMonthArray被声明为static,因此它不是实例变量 - 它是一个类变量,由所有实例共享并可供类方法访问。

-count只是一条可以发送到MonthArray的邮件,它始终返回12,即一年中的月数。那条消息没有做任何实际的工作。对于未明确声明的属性,它更像是一个getter。

[self count]实例的出现位置是MonthArray实例向自身发送消息的位置。在其他语言中,它可能写成this.count()

答案 2 :(得分:0)

首先,类方法缺少返回类型 - 让我们修复:

+ (MonthArray *)monthArray {...}

现在提出第一个问题:
实例方法和类方法之间的区别是目标,您可以调用它。顾名思义,您可以在类对象上调用类方法。这方面的例子是

// call a factory-method of NSArray to create a new array:
NSArray *array = [NSArray arrayWithObject:@"foo"];
// obtain the current notification-center
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
// obtain a singleton
NSApplication *app = [NSApplication sharedApplication];

因此正好一个对象,您可以调用该方法 - 在这种情况下,检索由此类实现的 singleton

有了这个,我们来看你的第二个问题:
当您调用[MonthArray monthArray]时,将返回此类的唯一要创建的实例。但是,必须有一种方法可以将该实例存储在某个地方,以便以后可以检索它。您可以在static变量中执行此操作(在Java中,这将是一个类变量)。这几个月也是如此,只需要一次 仅存在objectAtIndex:以使用精简的Objective-C图层包裹原始C数组。请记住,C会很乐意让你做months[42]之类的事情 - 只会在以后的某个地方崩溃,因为你在那里获得的东西不太可能是NSString。

你的第三个问题:
self不是几个月!它是MonthsArray的一个实例,并且 - 正如此代码显然意图 - 唯一应该存在的实例(即,存储为sharedMonthsArray的对象)。作为MonthArray的一个实例,它会响应count选择器,并在发送此消息时返回12(请参阅-(unsigned)count的实现)。这不计算月份:你可以像这样改变几个月

NSString *months[] = { @"January", @"February", @"March",
@"April", @"May", @"June", @"July", @"August", @"September",
@"October", @"November", @"December", @"Dancing Hippo Month" };

它仍会返回12。