如何通过apple(NSString和NSCFString)实现群集模式中的行为 [英] How can i implement the behaviour as in cluster pattern by apple (NSString and NSCFString)
问题描述
我只是编写以下代码用于测试目的:
I am simply writing the following code for testing purpose:
NSString *aStr = [[NSString alloc] initWithFormat:@"Foo"];
aStr = [aStr initWithFormat:@"Bar"];//Crashed here
I我收到以下错误:
*** initialization method -initWithFormat:locale:arguments: cannot be sent to an abstract object of class __NSCFString: Create a concrete instance!
如果我写下面的代码发生同样的事情
If i write the following code same thing happen
NSString *aStr = [NSString alloc];
aStr = [aStr initWithFormat:@"Foo"];
aStr = [aStr initWithFormat:@"Bar"]; //Crashed here
通过google我知道 initWithFormat
将返回 NSCFString
对象。
我的问题是如果 NSCFString
是派生类 NSString
那么为什么我不能调用 initWithFormat
NSCFString
上的方法。如果可以停止可见性我如何在代码中实现。
By google I come to know that initWithFormat
will return the NSCFString
Object.
My question is if NSCFString
is derived class of NSString
then why I cannot invoke the initWithFormat
method on NSCFString
. If it is possible to stop the visibility how can I implement in the code.
推荐答案
让我们对如何<$ c进行一些调查$ c> NSString 类集群在内部工作:
Let's do some investigation on how NSString
class cluster works internally:
NSString *factory = [NSString alloc];
NSString *theInstance = [factory initWithString:@"I am constant"];
NSLog(@"factory class: %@, instance class: %@", [factory class], [theInstance class]);
输出为:
factory class: NSPlaceholderString, instance class: __NSCFConstantString
正如你所看到的, alloc
方法返回 NSPlaceholderString
的实例。它是一个工厂类,它实现了在 NSString
中声明的所有 init ...
方法。这些方法返回 NSString
的具体(私有)子类。在此示例中,它返回 __ NSCFConstantString
。
As you can see, the alloc
method returns an instance of NSPlaceholderString
. It is a "factory" class which implements all the init...
methods declared in NSString
. These methods return concrete (private) subclasses of NSString
. It returns __NSCFConstantString
in this example.
如果您将第一行更改为
NSString *factory = [NSMutableString alloc];
输出将更改为:
NSPlaceholderMutableString,实例类:__ NSCFString
NSPlaceholderMutableString, instance class: __NSCFString
因此,可变和不可变字符串有不同的工厂类,以及这些工厂返回不同的子类。
So there are different factory classes for the mutable and immutable strings, and those factories return different subclasses.
您甚至可以检查iOS运行时标头中私有子类的层次结构:这里和这里。
You can even check the hierarchy of private subclasses in iOS runtime headers: here and here.
现在让我们看看当我们在 __ NSCFConstantString
的实例上调用 initWithString:
时会发生什么。
Now let's see what happens when we call initWithString:
on an instance of __NSCFConstantString
we just created.
[theInstance initWithString:@"Crash"];
正如您所料 - 它崩溃了。在stacktrace中我们可以看到 - [NSString initWithCharactersNoCopy:length:freeWhenDone:]
方法被调用,抛出异常:
As you expected - it crashes. In the stacktrace we can see that -[NSString initWithCharactersNoCopy:length:freeWhenDone:]
method is called, throwing an exception:
'NSInvalidArgumentException',原因:'***初始化方法
-initWithCharactersNoCopy:length:freeWhenDone:无法发送到类__NSCFConstantString的抽象对象:创建具体的
实例!'
'NSInvalidArgumentException', reason: '*** initialization method -initWithCharactersNoCopy:length:freeWhenDone: cannot be sent to an abstract object of class __NSCFConstantString: Create a concrete instance!'
所以我们可以在 NSString
类中猜测这个初始值设定项实际上是一种抽象方法(在Objective-C中没有抽象方法,因此在调用时抛出异常)。
So we can guess that this initializer in NSString
class is actually an abstract method (kind of - there aren't abstract methods in Objective-C, so it throws an exception when called).
此方法在工厂类 NSPlaceholderString
中实现。但它在所有具体的子类中都没有 ,所以如果你调用任何 init ...
方法,它将调用 NSString
抛出异常的实现。
This method is implemented in the factory class NSPlaceholderString
. But it's not implemented in all the concrete subclasses, so if you call any of the init...
methods, it will call the NSString
implementation which throws the exception.
让我们把它们放在一起构建 NSString的一小部分
类集群。它真的很简单,可能与真正的实现完全不同,但我只想展示这个想法。
Let's put it all together and build a tiny part of the NSString
class cluster. It's really simplified and probably totally different than the real implementation, but I just wanted to show the idea.
@interface NSPlaceholderString : NSString
@end
@interface __NSCFConstantString : NSString
@end
@implementation NSString
+ (instancetype)alloc {
return [[NSPlaceholderString alloc] init];
}
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer {
[NSException raise:NSInvalidArgumentException format:@" initialization method -initWithCharactersNoCopy:length:freeWhenDone: cannot be sent to an abstract object of class %@: Create a concrete instance!'", [self class]];
return nil;
}
- (instancetype)initWithString:(NSString *)aString {
//this method has to call the "abstract" initializer somewhere. The real implementation is probably more complex, this single line is here for simplicity
return [self initWithCharactersNoCopy:[aString UTF8String] length:[aString length] freeWhenDone:YES];
}
@end
@implementation NSPlaceholderString
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer {
__NSCFConstantString *concreteClassInstance = ...; // create the concrete instance.
return concreteClassInstance;
}
@end
@implementation __NSCFConstantString
//implement all the needed methods here. But do NOT implement initWithCharactersNoCopy:length:freeWhenDone:
@end
这篇关于如何通过apple(NSString和NSCFString)实现群集模式中的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!