为什么 [NSMutableString stringWithString:@""] 有效?

发布于 2024-12-19 04:23:40 字数 817 浏览 5 评论 0 原文

只是想知道:

NSString 中有一个名为 +stringWithString: 的静态方法。 这在 NSMutableString 中没有被重新声明/覆盖,所以我们不能假设这将返回一个 NSMutableString。事实上,即使在 NSString 类中,返回类型也定义为 id 和 文档状态

返回值
通过复制 aString 中的字符创建的字符串。

我在理解为什么它起作用并返回 NSMutableString 的知识中缺少目标 C 的哪一部分?特别是因为基类 NSString 不知道我们想要返回一个可变字符串。

有人可能会说,在内部调用了 [Class alloc] ,这将生成一个 NSMutableString 类型的对象,但即使这是纯粹的猜测,因为我们没有源代码,并且 < code>stringWithString: 可以在内部做任何它想做的事情。

所有这些类方法都在子类中重新实现吗?如果是的话,为什么没有记录下来?

Just wondering:

In NSString there is a static method called +stringWithString:.
This is not redeclared/overridden in NSMutableString so we cannot assume that this will return an NSMutableString. In fact even in the NSString class the return type is defined as id and the doc states:

Return Value
A string created by copying the characters from aString.

What part of objective C am I missing in my knowledge to understand why this works and returns an NSMutableString? Especially because the base class NSString is not aware that we want a mutable string in return.

One could say that internally [Class alloc] is called which will generate an object of type NSMutableString, but even this is pure guesswork as we do not have the source code and stringWithString: could do whatever it wants internally.

Are all those class methods reimplemented in the subclass? And if yes why isn't this documented?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

霊感 2024-12-26 04:23:40

在 NSString 中有一个名为 +stringWithString: 的静态方法。

更恰当地说,它是一个类方法。

这没有在 NSMutableString 中重新声明/覆盖

在 cocoa 中,子类不需要重新声明该方法。事实上,它只会产生大量噪音(IMO)。它只需要重新定义方法来提供其自定义实现。

所以我们不能假设这将返回一个 NSMutableString。

我们必须假设它将返回一个可变字符串。子类可以根据需要重新定义其初始值设定项和便利构造函数,以满足所需的约定,而无需公开重新声明该方法 - 仅当基类的实现不足时才需要定义该方法。

我在理解为什么它起作用并返回 NSMutableString 的知识中缺少目标 C 的哪一部分?特别是因为基类 NSString 不知道我们想要返回一个可变字符串。

它“知道”是因为您编写了 [NSMutableString stringWithString:@"bah"] 而不是 [NSString stringWithString:@"bah"]。与实例方法一样,类方法有一个隐式的 self ,它允许它们通过类方法传递类型。因此,可以根据需要重新定义/覆盖类方法。类方法还可以使用 self 来确定或消息其类型(示例很快)。

有人可能会说,在内部调用 [Class alloc] ,它将生成一个 NSMutableString 类型的对象,但即使这也纯粹是猜测,因为我们没有源代码,而 stringWithString: 可以在内部做任何它想做的事情。

这不应该是猜测。在这种情况下,如果返回的是不可变字符串,您应该提交错误。否则,无论他们是否使用一个或多个定义,它都会像广告中所宣传的那样工作。

所有这些类方法都在子类中重新实现吗?

在便利构造函数的情况下,更常见的是通过指定的初始值设定项之一:

这样的实现可以采用以下形式:

@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];
}
...

如果是的话,为什么没有记录下来?

当唯一的区别是您所请求的类类型时,不应重新声明或重新记录它们,除非它们与基类有一些偏差或有特殊说明 - 即使在这种情况下,最好使用另一个名称创建一个方法。

In NSString there is a static method called +stringWithString:.

more approriately, it's a class method.

This is not redeclared/overridden in NSMutableString

In cocoa, the subclass does not need to redeclare the method. In fact, it would just produce a lot of noise (IMO). It only needs to redefine the method to provide its custom implementation.

so we cannot assume that this will return an NSMutableString.

We must assume that it will return a mutable string. A subclass can redefine its initializers and convenience constructors as needed in order to meet the required contracts without publicly redeclaring the method -- it only needs to define the method when the base's implementation is insufficient.

What part of objective C am I missing in my knowledge to understand why this works and returns an NSMutableString? Especially because the base class NSString is not aware that we want a mutable string in return.

It 'knows' because you have written [NSMutableString stringWithString:@"bah"] rather than [NSString stringWithString:@"bah"]. Like instance methods, class methods have an implicit self which allows them to pass the type through class methods. Therefore, class methods may be redefined/overridden as needed. The class methods may also use self to determine or message their type (example shortly).

One could say that internally [Class alloc] is called which will generate an object of type NSMutableString, but even this is pure guesswork as we do not have the source code and stringWithString: could do whatever it wants internally.

It should not be guesswork. In this case, you should file a bug if you were returned an immutable string. Otherwise, it works as advertised, regardless of whether they used one or more definitions.

Are all those class methods reimplemented in the subclass?

In the case of convenience constructors, it's more common to go through one of the designated initializers:

such an implementation could take the form:

@implementation NSString
+ (id)stringWithString:(NSString *)arg
{
    // self is either +NSString or +NSMutableString
    return [[[self alloc] initWithString:arg] autorelease];
}

although exceptions can often be made, and is often the case with optimized immutable/mutable types:

@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];
}
...

And if yes why isn't this documented?

They should not be redeclared or redocumented when the only difference is the class type which you have requested, unless they have some deviation from the base class or special note -- even in that case, it would be better to create a method with another name.

痞味浪人 2024-12-26 04:23:40

NSMutableStringNSString 的子类,因此任何调用 NSMutableString 的方法都可以正常工作,并返回一个 NSMutableString > 当它有意义时。我想到的唯一不遵循这一点的方法是copy,按照惯例它返回一个不可变的实例。

这就是为什么您的初始化方法返回 id 而不是具体实例,以及为什么所有类方法都应使用 [self alloc] 而不是 [MYActualClass alloc].

NSMutableString is a subclass of NSString thus any method called on NSMutableString can be expected to work appropriately, and return an NSMutableString when it makes sense. The only method that comes to mind that doesn't follow that though is copy which by convention returns an immutable instance.

This is why your initializer methods return id rather than a concrete instance, and why all class methods should use [self alloc] instead of [MYActualClass alloc].

若无相欠,怎会相见 2024-12-26 04:23:40

(贾斯汀说的话,但需要澄清)

在 NSString 中有一个名为 +stringWithString: 的静态方法。这
没有在 NSMutableString 中重新声明/重写,所以我们不能假设
这将返回一个 NSMutableString。事实上即使在 NSString 中
class 返回类型定义为 id ...

首先,Objective-C 没有静态方法。 Objective-C 有类方法。类方法的行为与实例方法完全相同(其中该类是元类的实例),并且可以继承、重写等...

因此,正如 NSMutableString 继承 characterAtIndex: 并且可以重写它来执行一些特殊的操作,如果需要,NSMutableString 可以对类方法执行相同的操作。

另请注意,类无需在标头中声明从其超类重写的方法。框架中的类通常不会显式声明重写方法,因为重写方法的行为应与父类完全相同,但会被重写以在子类要求的上下文中工作。

(What Justin said, but a clarification)

In NSString there is a static method called +stringWithString:. This
is not redeclared/overridden in NSMutableString so we cannot assume
that this will return an NSMutableString. In fact even in the NSString
class the return type is defined as id ...

First and foremost, Objective-C does not have static methods. Objective-C has class methods. Class methods behave exactly like instance methods (where the class is an instance of a metaclass) and can be inherited, overridden, etc...

Thus, exactly as NSMutableString inherits characterAtIndex: and can override it to do something special, if needed, NSMutableString can do the same for class methods.

Note also that there is no need for a class to declare a method in the header that it overrides from its superclass. The classes in the framework generally do not declare overridden methods explicitly because the overridden method should behave exactly as the parent, but is overridden to work within the context of the subclass's requirements.

大姐,你呐 2024-12-26 04:23:40

您可以像这样编写初始化程序:

+ (id) stringWithString: (NSString*) foo
{
    return [[self alloc] initWithString:foo];
}

现在,当您在 NSString 上调用此初始化程序时,[self alloc] 返回 NSString 并且您会得到一个NSString 返回的实例。但是当你调用[NSMutableString stringWithString:@"…"]时,[self alloc]消息的结果是NSMutableString,因此初始化器返回一个可变字符串。

You can write the initializer a bit like this:

+ (id) stringWithString: (NSString*) foo
{
    return [[self alloc] initWithString:foo];
}

Now when you call this initializer on NSString, [self alloc] returns NSString and you get an instance of NSString back. But when you call [NSMutableString stringWithString:@"…"], the result of the [self alloc] message is NSMutableString, and therefore the initializer returns a mutable string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文