在 Objective-C 上下文中使用工厂方法的目的是什么?
我对在objective-c中使用工厂方法有点困惑?这样做有什么用处?
在objective-c中使用工厂方法的例子是什么?
有点困惑。任何解释都会有所帮助!
在 Objective-C 上下文中使用工厂方法的目的是什么?
我对在objective-c中使用工厂方法有点困惑?这样做有什么用处?
在objective-c中使用工厂方法的例子是什么?
有点困惑。任何解释都会有所帮助!
Objective-C 没有其他编程语言中可用的构造方法。工厂方法本质上是Objective C 的构造方法。它们允许您为对象分配内存并初始化值。
在您的课程中,使用以下模式添加方法:
//Please follow Obj C naming conventions and name all init
//methods "initWith" then desc
-(id)initWithString:(NSString*)str {
if(self = [super init]) {
_someProperty = str;
_someOtherProperty = 0;
} return self;
}
//Please follow Obj C naming conventions and name all factory
//methods "myClassWith" then desc
+(instancetype)someClassWithString:(NSString*)str {
return [[self alloc] initWithString: str];
}
//Pretty much every factory method should have a matching init method, and
//only one init method should actually do the if(self = [super init] { /*do
//stuff*/ } return self;, the other init methods should call this one in some
//form or fashion
然后主要是,您可以执行以下操作:
SomeClass *myVariableName = [SomeClass someClassWithString:
@"Init with me please"];
它使您不必这样做:
SomeClass *myVariableName = [[SomeClass alloc] initWithString:
@"Init with me please"];
或这个:
SomeClass *myVariableName = [[SomeClass alloc] init];
[myVariableName mySetterMethod: @"Init with me please"];
[myVariableName setThatOtherProperty: 0];
工厂方法可以是返回新创建和初始化对象的任何类或实例方法。
在更严格的 Objective-C 上下文中,“类工厂方法”是类Class的任何类方法,其名称以class .. 开头,其前缀被去除,首字母小写。类的例子Foo
:
+(Foo*) fooWithParam:(NSDictionary*)param;
使用类工厂方法的一个原因是为了方便。如果你有一个类Foo
,它可以按照通常的方式创建如下:
Foo* foo = [[Foo alloc] initWithParam:param];
现在可以像这样使用方便的类工厂方法:
Foo* foo = [Foo fooWithParam:param];
但是,类工厂方法之所以有用还有其他原因:
例如,假设该initWithParam:
方法可能会失败。那么对于如何处理这个问题有很多困惑:是否应该在 init 中抛出异常?还是应该返回nil
?社区中存在关于正确方法的争论。这两种方法都有微妙的问题,包括无法避免的内存泄漏。
因此,在这种情况下,最合理的方法是使用带有错误参数的类工厂方法。在这里,您将获得一个 Foo 对象,如下所示:
NSError* error;
Foo* foo = [Foo fooWithParam:param error:&error];
现在,规则是:如果foo为 nil,则发生错误,可以通过输出参数error获取有关错误的详细信息:
if (foo) {
...
}
else {
NSLog(@"Error: %@", error);
}
通常,实现如下所示:
+ (Foo*) fooWithParam:(NSDictionary*)param error:(NSError**error) {
if ([param count] < 1) {
// invalid parameters
if (error) {
NSError* error = [NSError errorWithDomain:@"Foo" code:-1000 userInfo: ...];
}
return nil;
}
return [[self alloc] initWithParam:param]; // won't fail
}
另一个原因是实现“类集群”。这基本上意味着类工厂方法返回该类的子类。一个例子是NSStream
类。
该类NSInputStream
有一个类工厂方法:
+ (id)inputStreamWithFileAtPath:(NSString *)path;
这将返回一个专门的NSInputStream
.
在 ARC 的前期,有一个重要的细节:
从类工厂方法返回的对象是“自动释放的”。换句话说,接收对象的客户端并不拥有它——因此不需要释放它。
如今,使用 ARC,这些细节变得模糊:无论如何您都不需要手动释放这些对象。对象实际释放的方式和时间也取决于编译器优化。