Objective-C中方法旁边的加号和减号代表什么意思?

198

在Objective-C中,我想知道方法定义旁边的+-符号的含义。

- (void)loadPluginsAtPath:(NSString*)pluginPath errors:(NSArray **)errors;
4个回答

241
+表示一个类方法,-表示一个实例方法。
例如:
// Not actually Apple's code.
@interface NSArray : NSObject {
}
+ (NSArray *)array;
- (id)objectAtIndex:(NSUInteger)index;
@end

// somewhere else:

id myArray = [NSArray array];         // see how the message is sent to NSArray?
id obj = [myArray objectAtIndex:4];   // here the message is sent to myArray

// Btw, in production code one uses "NSArray *myArray" instead of only "id".

这里有另一个问题涉及类方法和实例方法之间的区别


77
好像“静态”的额外五个字符对他们来说有些太多了。 - Anon.
26
这些方法不是静态的,它们是类方法。它们可以被覆盖,并且是类层次结构中非常重要的一部分。在C语言中,“静态”有着非常不同的含义。 - bbum
5
@Avon,这就是苹果风格,他们的相机也会省略闪光灯,鼠标也没有右键。 =) - pokstad
15
@bbum说得对。Java重新定义了“static”关键字的含义并非完全是C语言先前的错。虽然在C中它的用法可能并不是非常直观,但在Java中似乎更不直观。我本来会认为static是dynamic(动态)的相反——表示某物不会改变。当然,在苹果采用它作为OS X的编程语言之前,Objective-C语言已经存在了近15年。 - Quinn Taylor
3
静态方法与类方法的区别:在MYBaseClass和它的子类MYSubClass中定义方法+foo。NSArray *classes = @ [[MYBaseClass class],[MYSubClass class]]; [classes makeObjectsPerformSelector:@selector(foo)]; 这将无法使用静态方法。虽然如此,我也更喜欢@classmethod@method之类的东西。为什么这么简洁呢...? - uliwitness
显示剩余6条评论

55

(+) 用于类方法,(-) 用于实例方法。

(+) 类方法:

声明为静态的方法,可以在不创建类实例的情况下调用。类方法只能操作类成员,无法操作实例成员,因为类方法无法访问实例成员。除非在该类的实例上调用它们,否则无法从类方法内部调用类的实例方法。

(-) 实例方法:

需要先创建一个类的实例才能调用。需要使用 new 关键字创建类实例。实例方法作用于类的特定实例。实例方法不声明为静态。

如何创建?

@interface CustomClass : NSObject

+ (void)classMethod;
- (void)instanceMethod;

@end

如何使用?

[CustomClass classMethod];

CustomClass *classObject = [[CustomClass alloc] init];
[classObject instanceMethod];

19

+方法是类方法-即没有访问实例属性的方法。用于像alloc或类的helper方法这样不需要访问实例变量的方法。

-方法是实例方法-与对象的单个实例相关。通常用于类上的大多数方法。

有关更多详细信息,请参见语言规范


实际上,类方法确实可以访问实例变量,只是没有像self那样的实例,而是类。它们仅仅没有与实例相关联,并且方法查找不是通过实例,而是通过类来进行的。尽管如此,你仍然可以这样做:+exchangeIVarOf: (MYObject*)a with: (MYObject*)b { MYObject* x = a->ivar; a->ivar = b->ivar; b->ivar = x; } - uliwitness

5
苹果公司在「方法和消息」章节中给出了这方面的明确解释,详见此链接:https://developer.apple.com/library/mac/referencelibrary/GettingStarted/RoadMapOSX/books/WriteObjective-CCode/WriteObjective-CCode/WriteObjective-CCode.html
简而言之:

+表示「类方法」

(即可在未实例化类的情况下调用方法)。因此你可以这样调用该方法:
[className classMethod]; 

- 表示实例方法

你需要先实例化一个对象,然后才能在对象上调用该方法。你可以手动像这样实例化一个对象:

SomeClass* myInstance = [[SomeClass alloc] init];

这实际上为对象分配内存空间,然后在该空间中初始化对象-这是一种简单化的方式来理解它。您可以将对象分配和初始化分开,但是绝不要这样做,因为它可能会导致与指针和内存管理相关的严重问题。

然后调用实例方法:

[myInstance instanceMethod]

在Objective-C中获取一个对象实例的另一种方式是这样的:

NSNumber *myNumber = [NSNumber numberWithInt:123];

这段代码调用了NSNumber类的 'numberWithInt' 类方法,该方法是一个“工厂”方法(即提供给您一个“现成实例”的方法)。

Objective-C还允许直接使用特殊语法创建某些对象实例,比如对于像这样的字符串:

NSString *myStringInstance = @"abc";


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接