我正在慢慢地,但肯定地通过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
以下是我的问题(我为没有创建多个主题而道歉,但从我所知道的内容 - 这些是非常基本的。)
显示+ monthArray时究竟是什么意思?我知道+表示它是一个类方法,但我不完全理解它有什么含义。它究竟与普通方法有什么不同?
此代码中整个sharedMonthArray ivar的目的是什么?我的意思是,objectAtIndex:方法是从几个月的字符串中拉出来的,那么重点是什么?
[自我统计]方法中的“自我”是什么?我的意思是,我明白这应该是几个月,但我在哪里可以看到这个程序?什么使[自我计数]计算月份而不计算MonthArrays的数量?
对不起,如果我的问题是超级小学,我还在学习 - 提前感谢您的帮助。
答案 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。