Objective-C中的类和实例方法有什么区别,我应该在何时使用它们?
答案 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文件中定义方法时也适用相同的规则。