只是想知道:
在NSString
中有一个名为+stringWithString:
的静态方法。
这不会在NSMutableString
中重新声明/覆盖,因此我们无法假设这将返回NSMutableString
。事实上即使在NSString类中,返回类型也定义为id
和doc states:
返回值
中的字符创建的字符串
通过复制aString
。
在我的知识中,我缺少什么目标C来理解为什么这会起作用并返回NSMutableString
?特别是因为基类NSString
不知道我们想要一个可变字符串作为回报。
可以说内部[Class alloc]
会被调用,它会生成NSMutableString
类型的对象,但即使这是纯粹的猜测,因为我们没有源代码而且stringWithString:
可以做无论内心想要什么。
是否所有这些类方法都在子类中重新实现?如果是,为什么不记录这个?
答案 0 :(得分:6)
在NSString中有一个名为+ stringWithString的静态方法:
更合适的是,这是一种课堂方法。
这不会在NSMutableString
中重新声明/重写
在cocoa中,子类不需要重新声明该方法。事实上,它只会产生很多噪音(IMO)。它只需要重新定义方法来提供自定义实现。
所以我们不能假设这会返回一个NSMutableString。
我们必须假设它将返回一个可变字符串。子类可以根据需要重新定义其初始化器和便捷构造器,以便在不公开重新声明方法的情况下满足所需的合同 - 它只需要在基础实现不足时定义方法。
在我的知识中,我缺少什么目标C来理解为什么这会起作用并返回一个NSMutableString?特别是因为基类NSString不知道我们想要一个可变的字符串作为回报。
它'知道'因为你写了[NSMutableString stringWithString:@"bah"]
而不是[NSString stringWithString:@"bah"]
。与实例方法类似,类方法具有隐式self
,允许它们通过类方法传递类型。因此,可以根据需要重新定义/重写类方法。类方法也可以使用self
来确定或消息它们的类型(例子很快)。
可以说内部[类alloc]被调用,它将生成NSMutableString类型的对象,但即使这是纯粹的猜测,因为我们没有源代码和stringWithString:可以在内部做任何想做的事。
不应该猜测。在这种情况下,如果您返回 immutable 字符串,则应该提交错误。否则,无论是否使用了一个或多个定义,它都会像宣传的那样工作。
是否所有这些类方法都在子类中重新实现?
对于便捷构造函数,通过其中一个指定的初始值设定项更为常见:
这样的实现可以采取以下形式:
@implementation NSString
+ (id)stringWithString:(NSString *)arg
{
// self is either +NSString or +NSMutableString
return [[[self alloc] initWithString:arg] autorelease];
}
虽然通常可以做出例外情况,但优化的不可变/可变类型通常也是如此:
@implementation NSString
+ (id)stringWithString:(NSString *)arg
{
return [arg imp_isMutable] ? [[[self alloc] initWithString:arg] autorelease] : arg;
}
...
@implementation NSMutableString
+ (id)stringWithString:(NSString *)arg
{
return [[[self alloc] initWithString:arg] autorelease];
}
...
如果是,为什么不记录这个?
当唯一的区别是你要求的类类型时,它们不应该被重新声明或重新编写,除非它们与基类或特殊注释有一些偏差 - 即使在这种情况下,最好创建一个方法用另一个名字。
答案 1 :(得分:3)
NSMutableString
是NSString
的子类,因此任何调用NSMutableString
的方法都可以正常工作,并在有意义时返回NSMutableString
。我想到的唯一不会遵循的方法是copy
,它按惯例返回一个不可变的实例。
这就是为什么你的初始化方法返回id
而不是具体实例,以及为什么所有类方法都应该使用[self alloc]
而不是[MYActualClass alloc]
。
答案 2 :(得分:3)
您可以像这样编写初始化程序:
+ (id) stringWithString: (NSString*) foo
{
return [[self alloc] initWithString:foo];
}
现在,当您在NSString
上调用此初始值设定项时,[self alloc]
会返回NSString
并返回NSString
的实例。但是当您调用[NSMutableString stringWithString:@"…"]
时,[self alloc]
消息的结果为NSMutableString
,因此初始值设定项会返回一个可变字符串。
答案 3 :(得分:3)
(Justin说,但澄清)
在NSString中有一个名为+ stringWithString的静态方法:这个 在NSMutableString中没有重新声明/重写,所以我们不能假设 这将返回一个NSMutableString。实际上甚至在NSString中 class返回类型定义为id ...
首先, Objective-C没有静态方法。 Objective-C有类方法。类方法的行为与实例方法完全相同(其中类是元类的实例),并且可以继承,覆盖等...
因此,正如NSMutableString
继承characterAtIndex:
并且可以覆盖它以执行特殊操作,如果需要,NSMutableString
可以对类方法执行相同的操作。
另请注意,类不需要在头中声明它从超类中重写的方法。框架中的类通常不显式地声明重写方法,因为重写的方法应该与父类完全相同,但是被覆盖以在子类的需求的上下文中工作。