在Objective-C中,何时应该使用类方法,何时应该使用实例方法?

时间:2010-06-30 05:32:40

标签: iphone objective-c

Objective-C中的类和实例方法有什么区别,我应该在何时使用它们?

5 个答案:

答案 0 :(得分:12)

使用疲惫的旧车类比......

想象一个类,就像它是一个制作类的实例的工厂。例如,您可能有一个Car类,您可以声明一个类似的方法:

+ carWithColor: (NSColor *) aColor;

然后该方法将创建一个新的Car实例,设置颜色并返回它:

 + carWithColor: (NSColor *) aColor
 {
     Car *aCar = [[[self alloc] init] autorelease];
     [aCar paintWithColor: aColor];
     return aCar;
 }

现在,Car类将声明一个允许绘制汽车的实例方法。为什么是实例方法?因为每辆车都可以有不同的颜色(并且汽车的颜色可能存储在实例变量中)。

- (void) paintWithColor: (NSColor *) aColor
{
    ... do your paint stuff here ...
}

Objective-C文档的Objects, Classes, and Messaging部分对此进行了解释。

答案 1 :(得分:7)

这是一篇旧帖子,但由于它首先出现在谷歌搜索中,我以为我会添加它。

我不打算谈论用作工厂方法的类方法。我想谈谈它们在实用方法中的用法。您可以/应该使用类方法来实现独立于状态的实用程序方法。这是什么意思?好吧,例如,如果您以相同的方式为所有实例格式化日期,那么这是一个应该是类方法的实用方法。想想像螺丝刀一样的实用方法。每次想要使用它时,您都不需要创建螺丝刀的新实例。螺丝刀保持不变。因此,例如,我有一个类,其中包含一个私有方法,该方法生成一个用于显示视图的emDashes字符串。该方法不依赖于状态,因此不会因实例而异。想想像常量这样的类实用程序方法。

+ (NSString *)emDashString {
return @"   \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014";

}

您可以在类中统一调用此方法(在我的示例中是私有的),如下所示:

NSString *string = [[self class] emDashString ];

我故意选择了一个微不足道的例子来推动这一点。如果你在课堂上不止一次需要这个字符串,你只会打扰这个类实用程序方法。请注意,我没有按名称引用类,而是使用[self class]来调用它,因为这是在内部调用的。如果它已暴露,你想从另一个类调用它,那么像往常一样通过类名引用它。

答案 2 :(得分:0)

实例方法使用类的实例执行操作:

NSString *myString;
myString = [[[NSString alloc] initWithString:@"Hello, world."] autorelease];
NSLog (@"myString's length: %u", [myString length]); // instance method

方法可以在不依赖于对象实例的情况下执行类特定的事务,通常返回类的实例或其他特定于类的结果:

NSLog (@"%@", [NSString stringWithString:@"Hello, world."]); // class method

我认为看到不返回某些东西的类方法可能很少见。

答案 3 :(得分:0)

您不需要同时实现这两者。在设计课程时,您可以使用任何一个选项。

实例方法可以对类的实例进行操作。这可以获取或设置属性,或导致您只希望该实例执行的行为。您需要实际拥有一个实例才能使用它。这些可以使用或更改实例的状态。

// Notional instance methods
myHouse.color = blueColor;

[myCar accelerate];
speed = myCar.speed;

类方法根据类存在的概念进行操作。它可用于创建实例,或执行不依赖于实例的计算。您可能有一个自定义数学助手类,它基本上包含函数。

// Notional class method uses
myString = [NSString stringWithFormat:@"&f", floatToConvert];

myResult = [MyMathHelper MyFunctionWithInput:myInput];

答案 4 :(得分:-1)

类方法签名以+为前缀,实例方法带 - 如此在头文件中声明如下所示:

-(void)setAllThings:(NSArray*)things; //instance method
+(void)setAllClassThings:(NSArray*)things; //class method

当然,在.m文件中定义方法时也适用相同的规则。