【问题标题】:Can I include NSError** as a parameter in init in Objective-C?我可以在 Objective-C 的 init 中包含 NSError** 作为参数吗?
【发布时间】:2015-01-02 12:25:42
【问题描述】:

我的 iOS 应用程序从 REST 服务获取 JSON。 JSON 包含状态代码和数据。 如果代码为 200,则数据为请求的对象,否则数据为错误描述。

JSON 可用于构建多种对象,因此我创建了一个工厂类,在其构造函数中获取 json 数据,实例方法根据需要将数据解析为不同的对象。

我的问题是,如果状态码不是 200,是否可以在构造函数中包含 NSError** 作为参数。方法头看起来像这样:

-(instancetype) initWithData:(NSData *) json error: (NSError **) error;

【问题讨论】:

    标签: ios objective-c json nsjsonserialization


    【解决方案1】:

    虽然这在语法上完全没问题,但这种方法在功能方面存在问题。

    问题在于,当初始化器的调用不成功并返回nil 时,对象的空间仍然被分配(然后立即释放),因为您无法控制它。 allocin的调用

    MyObj *obj = [[MyObj alloc] initWithData:data error:&err];
    

    发生在您的代码之外。

    最好对调用者隐藏初始化程序,并公开一个类“工厂”方法,如下所示:

    +(instancetype) myclassWithData:(NSData *) json error: (NSError **) error;
    

    这样您就可以决定何时调用alloc,这样当您确定没有要创建的对象时,就不会有无用的内存分配/释放。

    【讨论】:

    • 我认为他仍然需要这个对象,因为他没有提到返回 nil 但是是的,这是有道理的......
    • 那是错误的。你会在调用者的某个地方有一个 NSError*,就像使用 NSError** 的任何其他方法一样。这很不寻常,我从未真正看到它完成过,但没有理由不这样做。
    • @gnasher729 请指出我的答案中我说它不起作用或错误的地方(提示:我没有)。在写负面评论之前阅读答案通常是个好主意。
    • 你说有问题。 1.这个没问题。 2.它不依赖于一个输出参数。我同意“工厂”是更好的方法,但便利分配器并不是更好,因为它可能会返回一个自动释放的对象,该对象的寿命可能会更长。如果你现在想使用“工厂”方法,你应该使用new分配器。
    • @AminNegm-Awad 我说分配和及时释放空间有问题,以防出现错误,这个问题显然存在。
    【解决方案2】:

    当然,这可能是不寻常的,因为我不记得有任何 iOS API 在 init 中执行此操作,但这并没有错……

    【讨论】:

    • 这是一个相当有名的例子:-[NSString initWithContentsOfFile:encoding:error:]
    【解决方案3】:

    没关系。我这样做了很多次。考虑到在 Objective-C 中对象构造不是语言特性,而是框架的一部分。因此初始化器不是特殊的方法。初始化器的唯一特殊情况是它们消耗self 并转移返回值的所有权。但这与out参数无关。

    这是不寻常的,因为初始化程序通常不会中断。所以通常你根本不需要它。

    【讨论】:

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