【问题标题】:ARC forbids autorelease?ARC禁止自动释放?
【发布时间】:2013-07-11 21:08:25
【问题描述】:

ios 新手,尝试从函数返回 NSString。据我了解,我需要[NSString... alloc] init] 才能创建要返回的字符串。另外,因为我打电话给alloc,我想我必须自己自动释放对象但是我收到消息“ARC 禁止发送'autorelease'的显式消息”所以..当我完成后如何告诉 ios那分配的NSString?

- (NSString *) generateUID
{
    char foo[32];
    // create buffer of all capital psuedo-random letters
    for (int i = 0; i < sizeof(foo); i++)
       foo[i] = (random() % 25) + 65; // 0-25 + CAPITAL_A

    NSString *uid = [[NSString alloc] initWithBytes:foo length:sizeof(foo) encoding:NSASCIIStringEncoding];
    NSLog (@"uid: %@", uid);
    return (uid);
}

【问题讨论】:

  • 长话短说:ARC 为您处理。您应该在 Apple Dev 网站上阅读 ARC。

标签: iphone ios nsstring


【解决方案1】:

ARC = 自动引用计数 = 编译器根据对代码的分析添加必要的发布和自动发布。你当然看不到这一点,因为它发生在幕后。正如 sosbom 在他的评论中提到的,你真的应该阅读适用的documentation on the Apple website

【讨论】:

  • 谢谢 - 很棒的文档:“ARC 负责内存管理,因此 Person 和 NSNumber 对象都不会泄露。”
【解决方案2】:

你没有。

autorelease 只是为了兼容性,在 iOS 5 之前,您必须这样做:

Thing *myThing = [[Thing alloc] init]; // Retain count: 1
[myArray addObject:myThing];           // Retain count: 2
[myThing release];                     // Retain count: 1

通过上面的代码,持有对象的责任交给了数组,当数组被删除时,它会释放它的对象。

或者在自动释放的情况下。

- (MyThing*)myMethod
{
    return [[[MyThing alloc] init] autorelease];
}

然后它会在对象到达 NSAutoReleasePool 后释放该对象,并在耗尽后将其移除。

ARC 现在会处理这个问题,它几乎会为您插入缺失的部分,因此您不必担心它,它的美妙之处在于您可以获得引用计数的优势(与垃圾收集器相比) ),代价是增加编译时间检查以执行 ARC 步骤,但您的最终用户并不关心编译时间。

除此之外,您现在拥有 strongweak(与它们的非 ARC 兄弟姐妹 retainassign 相比,后者对于非保留的东西仍然有用),你会得到一个不错的无需用眼睛跟踪代码,也无需用左手计算保留计数,即可体验编程体验。

【讨论】:

  • 感谢您的澄清。在内存管理方面,从一个版本到下一个版本的 ios SDK 似乎存在很多差异。这使得查找示例有点棘手。
【解决方案3】:

简短的回答是你没有! ARC 将为您处理内存管理。 当 ARC 开启时,编译器会插入适当的内存管理语句,例如保留和释放消息。

最好使用 ARC,因为编译器对对象的生命周期有更好的了解,并且不太容易出现人为错误。

关于 ARC 的另一件需要注意的重要事项。 ARC 与传统的垃圾收集相同。没有单独的进程或线程在后台运行,就像 java 的 GC 一样,它会在不再引用对象时删除对象。可以将 ARC 视为编译时垃圾收集 :)。

唯一需要注意的是引用循环和在 Objective-C 和 Obj-C++/C 之间桥接指针/对象。你可能想查找http://en.wikipedia.org/wiki/Weak_reference

希望对你有帮助

【讨论】:

    【解决方案4】:

    一般来说,你应该在你的类中定义一个构造方法,并将分配逻辑放在那个方法中。然后,由于 alloc/init 方法总是返回 (id) 并且它不是非常安全的类型,因此很难产生类型转换错误。这就是像 NSString 这样的内置类所做的,例如 [NSString stringWithString:@"foo"]。这是一个不错的小块,您可以使用它来编写既适用于较旧的非 arc 编译又适用于启用 arc 的代码。

    + (AVOfflineComposition*) aVOfflineComposition
    {
      AVOfflineComposition *obj = [[AVOfflineComposition alloc] init];
    #if __has_feature(objc_arc)
      return obj;
    #else
      return [obj autorelease];
    #endif // objc_arc
    }
    

    然后您声明该方法并创建对象的实例,如下所示:

    AVOfflineComposition *obj = [AVOfflineComposition aVOfflineComposition];
    

    最好使用上述方法,因为它是类型安全的,并且与 arc 与 non-arc 的代码相同。如果您尝试将返回的对象分配给其他类型的变量,编译器会报错。

    【讨论】:

      猜你喜欢
      • 2013-07-10
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 2012-03-16
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      相关资源
      最近更新 更多