0

我似乎无法在任何地方找到答案。我在为 iOS 开发的 Objective-C 中使用手动内存管理。

我编写了一个从十六进制字符串中获取 UIColor 的便捷函数。在其中,它返回

[[UIColor alloc] initWithRed:... alpha:alpha]

显然在某些平台上(我们有一些设备,包括 iOS 8-9),该对象将在退出函数时被销毁,因此它返回的 UIColor* 无法使用。所以现在,我们将其更改为

[[[UIColor alloc] initWithRed:... alpha:alpha] retain]

我的问题是当我使用完这个对象后,我必须释放它两次吗?一次分配,一次保留?这对我来说似乎很奇怪,我在任何地方都无法在网上找到它。

如果我不保留,它会在退出函数时(在某些平台上)使函数无用。如果我保留,我需要在完成后释放两次?

编辑:

https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

“...,它通常保证在接收它的方法或函数内保持有效。如果您希望它在该范围之外保持有效,您应该保留或复制它。”

所以我没有做任何不寻常的事情。文档说如果“我希望它在函数范围之外保持有效”,我“应该保留它”。我会尝试@FreeNickname 的建议。这是最有意义的。

4

3 回答 3

2

你说:

我写了一个方便的函数来获取UIColor一个十六进制字符串。在其中,它返回

[[UIColor alloc] initWithRed:... alpha:alpha]

根据Basic Memory Management Rules,正确的内存管理由您的方法名称决定:

  • 如果你的方法名不是以“alloc”、“new”、“copy”或“mutableCopy”开头,那么你应该返回一个autorelease对象:

    - (UIColor *)colorWithHexString:(NSString *)hexString {
        ...
        return [[[UIColor alloc] initWithRed:... alpha:alpha] autorelease];
    }
    
  • 如果您的方法名称确实以“alloc”、“new”、“copy”或“mutableCopy”开头,那么您可以像上面一样返回一个对象:

    - (UIColor *)newColorWithHexString:(NSString *)hexString {
        ...
        return [[UIColor alloc] initWithRed:... alpha:alpha];
    }
    

    请注意,这种模式不如上述colorWithHexString.

(注意,这种由方法名前缀决定的内存管理在历史上只是最佳实践,但现在,为了与 ARC 代码的互操作性,这一点至关重要。在手动引用计数代码中始终遵循上述规则。)

现在,如果调用您的便捷初始化程序的代码允许释放对象,那么问题出在该代码上,而不是您的便捷初始化程序。不要开始向retain你的初始化程序添加额外的语句,因为调用它的东西不能正确管理它的内存。

相反,请确保调用代码执行, 本身的结果的正确retain(和最终) 。releasecolorWithHexString

顺便说一句,Xcode 的静态分析器 ( shift++ command)B非常擅长分析手动引用计数代码并识别问题。


在编辑您的问题时,您引用了文档:

如果您从程序的其他地方收到一个对象,通常保证它在接收它的方法或函数内保持有效。如果您希望它在该范围之外保持有效,您应该retaincopy它。如果你试图释放一个已经被释放的对象,你的程序就会崩溃。

这并不是说您的便利初始化程序应该发出retainor copy。也就是说,调用的代码colorWithHexString负责建立自己对通过orUIColor返回的对象的所有权声明,如上所述。retaincopy

于 2016-06-04T17:11:47.827 回答
0

我认为您正在寻找在像您这样的情况下使用的自动释放的概念。它本质上是一种向新创建的对象发送延迟消息的方法,以便调用者在必要时release有机会收到它,否则在处理时它会被销毁。retainautoreleasepool

于 2016-06-04T15:33:00.667 回答
0
于 2016-06-05T04:57:53.553 回答