[英]Why does [NSMutableString stringWithString:@“”] work?
就是想:
在NSString
有一個名為+stringWithString:
的靜態方法+stringWithString:
。 這不會在NSMutableString
重新聲明/重寫,因此我們不能假設這將返回NSMutableString
。 事實上,即使在NSString類中,返回類型也被定義為id
, doc指出 :
回報價值
通過復制aString
的字符創建的字符串。
在我的知識中,我缺少什么目標C來理解為什么這會起作用並返回一個NSMutableString
? 特別是因為基類NSString
不知道我們想要一個可變字符串作為回報。
可以說內部[Class alloc]
被調用,它將生成一個NSMutableString
類型的對象,但即使這是純猜測,因為我們沒有源代碼和stringWithString:
可以在內部做任何想做的事情。
是否所有這些類方法都在子類中重新實現? 如果是,為什么不記錄這個?
在NSString中有一個名為+ stringWithString的靜態方法:
更合適的是,它是一種類方法。
這不會在NSMutableString中重新聲明/重寫
在cocoa中,子類不需要重新聲明該方法。 事實上,它只會產生很多噪音(IMO)。 它只需要重新定義方法以提供其自定義實現。
所以我們不能假設這會返回一個NSMutableString。
我們必須假設它將返回一個可變字符串。 子類可以根據需要重新定義其初始化器和便捷構造器,以便在不公開重新聲明方法的情況下滿足所需的合同 - 它只需要在基礎實現不足時定義方法。
在我的知識中,我缺少什么目標C來理解為什么這會起作用並返回一個NSMutableString? 特別是因為基類NSString不知道我們想要一個可變字符串作為回報。
它'知道'因為你寫了[NSMutableString stringWithString:@"bah"]
而不是[NSString stringWithString:@"bah"]
。 與實例方法類似,類方法具有隱式self
,允許它們通過類方法傳遞類型。 因此,可以根據需要重新定義/重寫類方法。 類方法也可以使用self
來確定或消息它們的類型(例子很快)。
可以說內部[類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];
}
...
如果是,為什么不記錄這個?
當唯一的區別是你要求的類類型時,它們不應該被重新聲明或重新編寫,除非它們與基類或特殊注釋有一些偏差 - 即使在這種情況下,最好用另一個名稱創建一個方法。
NSMutableString
是NSString
的子類,因此任何在NSMutableString
調用的方法都可以正常工作,並在有意義時返回NSMutableString
。 我想到的不遵循,雖然唯一的方法是copy
其按照慣例返回一個不可改變的實例。
這就是為什么你的初始化方法返回id
而不是具體實例,以及為什么所有類方法都應該使用[self alloc]
而不是[MYActualClass alloc]
。
您可以像這樣編寫初始化程序:
+ (id) stringWithString: (NSString*) foo
{
return [[self alloc] initWithString:foo];
}
現在,當你調用這個初始化NSString
, [self alloc]
返回NSString
,你會得到的一個實例NSString
回來。 但是當你調用[NSMutableString stringWithString:@"…"]
, [self alloc]
消息的結果是NSMutableString
,因此初始化器返回一個可變字符串。
(賈斯汀說,但澄清)
在NSString中有一個名為+ stringWithString的靜態方法: 這不會在NSMutableString中重新聲明/重寫,因此我們不能假設這將返回NSMutableString。 實際上即使在NSString類中,返回類型也被定義為id ...
首先, Objective-C沒有靜態方法 。 Objective-C有類方法 。 類方法的行為與實例方法完全相同(其中類是元類的實例),可以繼承,重寫等等...
因此,正如NSMutableString
繼承characterAtIndex:
並且可以覆蓋它以執行特殊操作,如果需要, NSMutableString
可以對類方法執行相同操作。
還要注意,類不需要在頭中聲明它從超類中重寫的方法。 框架中的類通常不會顯式聲明重寫方法,因為重寫的方法應該與父類完全相同,但是被覆蓋以在子類的需求的上下文中工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.