Objective C ARC和Instance Variables iOS SDK

时间:2012-07-03 15:58:39

标签: objective-c ios

我们是否应该将我们希望保留的所有实例变量转换为私有属性,还是我错过了一些明显的东西?

@interface SomethingElse : Something  {

    NSMutableArray *someArray;

}

在此示例中,someArray在[NSMutableArray initWithObject:someObject]的方法中初始化,但不会保留。

我的特殊情况是我正在更新游戏,有很多实例变量,所以我想确保我为了未来版本的sdk而这样做。

6 个答案:

答案 0 :(得分:16)

  

我们是否应该转换我们希望的所有局部变量   保留私人财产还是我遗漏了一些明显的东西?

首先,您在示例中显示的变量是实例变量,而不是局部变量。局部变量在代码块内声明(例如在函数或方法内部,或在某些子块内部,例如条件语句的主体内),并且其生命周期仅限于声明它们的块的执行。实例变量在类中声明;该类的每个实例都获得自己声明的实例变量的副本。

其次,不,您不需要将所有实例变量转换为属性。 Instance variables are treated as strong references by default under ARC.一个属性实际上只是一个类,它为某些访问器提供了某些语义。只有一个实例变量并不意味着你必须为那个ivar提供访问器。 (有些人可能会说你应该,但你不必这样做。)

答案 1 :(得分:3)

@property与实例变量相同,除非您使用的是默认存储修饰符以外的其他对象。例如,如果您希望@property (copy) NSString *s;使用实例变量并记住每次设置变量时调用copy,或者使用@property(这更容易)。

答案 2 :(得分:1)

ARC的retain版本称为strong

基本上,您可以使用以下内容声明它:

@property (strong) NSMutableArray *someArray;

有关详细信息,请参阅What does the "strong" keyword do

使用属性而不是局部变量通常会更好,因为这些属性可以让你获得" free"的访问者/设置者,并且通常更容易使用。

答案 3 :(得分:1)

您在其他一些评论中描述了BAD_ACCESS问题。还有其他事情发生在这里。在ARC中,除非另有资格,否则您的ivars非常强大(在非ARC中,它们不会代表您发布)。

例如,当您在评论中向其他答案报告时,此ARC代码正常,没有BAD_ACCESS:

@interface ArcTestViewController ()
{
    NSMutableArray *_someArray;
}
@end

@implementation ArcTestViewController

- (void)dealloc
{
    _someArray = nil;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    _someArray = [[NSMutableArray alloc] initWithObjects:@"Mo", @"Larry", @"Curly", nil];
}

- (IBAction)checkIvarTouchUpInside:(id)sender 
{
    NSLog(@"%s _someArray = %@", __FUNCTION__, _someArray);
}

@end

您可能需要向我们展示您获取BAD_ACCESS的示例,因为它必须是其他内容。

在回答“属性”或“ivar”问题时,虽然我同情“总是使用属性”这个论点,但我个人使用属性来处理我需要提供外部访问器的任何东西,否则我使用私有ivars (不是在.h中,而是在.m文件的私有接口中)。这使得我的.h文件中的公共接口非常干净,并且在几个月后返回时很容易理解。如果您采用“始终使用房产”的方法,我只建议您对这些房产的公开声明应尽可能限制(如果可以,请将房产私有,如果您不愿意公开申报该房产)不需要提供读写访问等。)。

顺便说一下, Cocoa编码指南<{3}}是最佳实践的一个很好的参考。

答案 4 :(得分:0)

使用Obj-C 2.0及更高版本,似乎没有理由使用iVars。我个人没有永远使用过。这些物业只为你做了一切!

答案 5 :(得分:0)

感谢大家的回复。

如果我调用需要该对象的方法(使用cocos2d游戏引擎方法):

[self schedule:@selector(someMethod) interval:3.0];

如果我直接调用该对象而不将其放入cocos2d调度程序中,则该对象将被取消引用:

[self someMethod];

然后仍然有一个有效的指针。只是为了测试,我保留了它并保持不变。

现在的问题是,我们如何强制保留以防止ARC认为我们已经完成并释放它?

将实例变量更改为私有属性可以安全地进行,因此我们将以此作为答案。