【问题标题】:Objective C Convenience Method UseObjective C 便捷方法使用
【发布时间】:2014-03-24 21:19:05
【问题描述】:

我正在努力理解便利方法。

如果我有一个包含商店详细信息的 sqlite 数据库,并且在 FMResultSet 中返回这些商店详细信息。我在想,要将这些商店详细信息的数组创建为 Store 对象,最好的方法是使用便捷的方法一次性创建一个 Store 类型的对象并添加到数组中。

我用方便的方法创建的类如下

@interface StoreDetails : NSObject   

@property (nonatomic, strong) NSString *storeName;
etc etc etc

+ (instancetype)storeWithStoreName:(NSString *)storeName 
                   TelephoneNumber:(NSString *) 
                   telephoneNumber: etc .......

我的 ResultSet 循环如下所示?

NSMutableArray *Stores = [[NSMutableArray alloc] init];
while ([rs next]) {
    Store *store = 
    [Store storeDetailsWithStoreName:[rs stringForColumn:@"storename"] 
                            telephoneNumber:[rs stringForColumn:@"TelephoneNo"]];

    [Stores addObject:store];
}

我的想法是否正确,是不是最好如下。

NSMutableArray *Stores = [[NSMutableArray alloc] init];

while ([rs next]) {
    Store *store = [Store alloc] init];
    store.storeName = [rs stringForColumn:@"storename"];
    store.telephoneNumber = [rs stringForColumn:@"TelephoneNo"];
    [Stores addObject:store];
}

我试图理解的是为什么你会在菜鸟说话中使用一个而不是另一个,谢谢。

【问题讨论】:

  • 这可能是一个荒谬的想法,但你为什么不试试你的代码,看看它是否符合你的要求?!
  • 我正在尝试了解便捷方法的使用并知道我的代码有效,因此已经尝试过了。我想知道我做事是否正确。
  • 就个人而言,我对此类事情的便捷方法是传递记录集,处理Store对象的循环和创建并返回NSMutableArray
  • 我重新措辞了这个问题,也许可以更清楚地说明我在问什么

标签: objective-c class methods


【解决方案1】:

我认为您有一个很好的方法:在 Store 类的方法中初始化您的 Store 对象。

您定义的storeDetailsWithStoreName:... 方法是Apple 所谓的factory method 的一个很好的例子(假设您在其实现中没有做任何奇怪的事情)。这是一种很常见的模式。基金会有各种各样的例子:arrayWithCapacity:numberWithInt:等。

使用 ARC,这些工厂方法的最简单示例几乎与相应的 alloc/init 表达式相同,因为开发人员不再需要考虑自动释放对象。但是工厂方法仍然有很多用途,例如特殊的实例化模式,例如单例或享元,包括少量的通用转换或格式化代码以方便使用,实现class clusters 等。并且没有额外的一组括号和更少的缩进,非常方便。

instancetype 关键字是一个不错的选择。这允许您向Store 的子类发送相同的消息,并期望该方法将使用相同的 init 方法实例化子类的对象,如下所示:

+ (instancetype)storeWithStoreName:(NSString *)storeName 
                   telephoneNumber:(NSString *) 
                   ...
{
    return [[self alloc] initWithStoreName:...];
}

在上面的代码中,由于它是一个类方法,[self alloc] 中的self 是 Class 对象(Store 或 Store 的子类),而不是 Store 的特定实例。这就是允许在运行时创建正确类的实例的原因,具体取决于您调用[Store storeWithStoreName:...] 还是[MoreSpecificStoreSubType storeWithStoreName:...]

工厂方法的替代方案,或者说是对它的真正补充,是在你的 Store 类中声明一个自定义的 init 方法:

- (id)initWithStoreName:(NSString *)storeName
        telephoneNumber:(NSString *)telephoneNumber ...

...并直接在循环中使用它,而不是工厂方法。同样,对于 ARC,两者之间没有太大区别,除非您想在工厂方法中做额外的工作。您可以拥有init 方法的多个变体;标准做法是让他们都调用最详细的init方法,称为designated initializer

我建议花时间阅读有关类设计标准的 Apple 文档页面(我链接到上面的一些页面)。由于其中有很多更多是基于约定而不是语言设计限制,因此了解良好设计的模式和最佳实践以及特殊方法的正确行为非常重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2012-11-25
    相关资源
    最近更新 更多