Objective c 我们真的需要一个安全的发布宏吗?

Objective c 我们真的需要一个安全的发布宏吗?,objective-c,Objective C,相当多的人似乎使用宏,例如 #define SAFE_RELEASE(X) [X release]; X = nil; (包括我自己) 我一直在重新评估我为什么要使用它,并想收集一些意见 使用此宏的目的(我认为)是,如果在释放对象后意外使用该对象,则不会出现错误的访问异常,因为当对象为零时,objective-c会很高兴地忽略它 我觉得这有可能掩盖一些模糊的bug。当您再次尝试使用X时,程序崩溃可能更可取。这样,在测试期间,您可以发现问题并改进代码 这个宏鼓励懒惰编程吗 思想?你不需要它,但

相当多的人似乎使用宏,例如

#define SAFE_RELEASE(X)  [X release]; X = nil;
(包括我自己)

我一直在重新评估我为什么要使用它,并想收集一些意见

使用此宏的目的(我认为)是,如果在释放对象后意外使用该对象,则不会出现错误的访问异常,因为当对象为零时,objective-c会很高兴地忽略它

我觉得这有可能掩盖一些模糊的bug。当您再次尝试使用X时,程序崩溃可能更可取。这样,在测试期间,您可以发现问题并改进代码

这个宏鼓励懒惰编程吗


思想?

你不需要它,但拥有它很方便。我在我的应用程序中使用类似的东西。你可以认为它是“懒惰”的,但是当你有大约20个对象时,手动写出来会变得乏味。p> 我想你讨论了你问题中的所有利弊,所以我没有太多的补充。就我个人而言,我不使用构造。正如您所建议的,它可以用来掩盖人们不能正确理解内存管理的地方。我的偏好是修复bug,而不是修复症状

然而,我不时看到的一个妥协是:

  • 使其在开发过程中崩溃
  • 执行
    var=nil在生产代码中
通过这种方式,它可能对付费客户更加可靠,并且在开发早期仍然崩溃


我对此也不感兴趣,因为你对你的用户使用不同的代码,仅仅因为有缺陷的版本持续运行并不意味着它做了正确的事情。不崩溃但破坏数据库是不可取的行为…

我认为这是一种很好的行为,或者在适用的情况下使用self.myVar=nil之类的等效行为。在很多情况下,您不能简单地将nil赋值,并假设以后的任何访问都是一个bug

例如,在UIKit中,当操作系统发出请求时,释放尽可能多的资源是一种良好的行为。例如

- (void)didReceiveMemoryWarning 
{
    [myCachedData release];
    [super didReceiveMemoryWarning];
}

现在,下次使用我的类时,我如何知道myCachedData现在无效?唯一的方法(除了使用另一个变量作为标志)是在释放myCachedData后将其设置为nil。而将这两行冗长乏味的文字浓缩成一行正是安全发布的目的。

我也在研究同样的问题。通过阅读,我得到了这样的东西:

#define DEBUGGING
    //#define PRODUCTION

#ifdef DEBUGGING
#define SAFE_RELEASE(X)  [X release]; 
#else
#define SAFE_RELEASE(X)  [X release]; X = nil;
#endif
因此,如果我正在开发,我会崩溃。在制作中,我没有


Scott正如Andrew指出的,在某些情况下,分配
nil
不仅可以避免bug,而且是必要的。只需考虑典型<代码> UIViewController <代码>代码

- (void)viewDidLoad {
  button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // autoreleased
  [button retain]; // keep alive
}

- (void)viewDidUnload {   // view has been removed
  [button release];
}

- (void)dealloc {     // destroying the view controller
  [button release];   // <-- problem
}
对于这些情况,宏是很好和有用的。为了更明确地说明它的功能,最好将其命名为RELEASE_和_NIL

#define RELEASE_AND_NIL(X)  [X release]; X = nil;

中的相关部分,用于回答此处不应提出的问题。-'没有什么实际问题需要解决:“我很好奇别人是否和我一样。”这很公平,但这是我面临的一个问题。问题是我应该继续使用这个宏吗?我不知道是否有充分的理由使用它?我想这与宏本身无关,而是与释放对象后将其设置为零的理论有关。如果您已经完成了对对象的访问,那么您可能不应该再次尝试访问它,如果您再次访问它,那么最好让它崩溃,这样您就可以解决特定的代码问题。i、 你为什么要再次访问它?我认为你是对的,在适用的情况下设置为零是正确的。我认为我陷入的陷阱是盲目地使用宏,没有过多地考虑它。这可能会导致在生产中很难追踪到错误-有关详细信息,请参阅我的答案。
#define RELEASE_AND_NIL(X)  [X release]; X = nil;