当我可以使用内联变量时,为什么要声明@property?

时间:2012-04-13 07:45:20

标签: objective-c memory-management ios5 initialization

我花了几天时间学习Objective-C,并对@property提出了一些问题。我有使用C#的经验,所以理解需要指针,初始化等。

以此为例:

 @interface MyClass : NSObject
 {
      IBOutlet UIImageView *image;
 }

 @property (retain, nonatomic) UIImageView *image

 @end

 @implementation MyClass
      @synthesise image
 @end

我了解@synthesise用于创建@property。但是我有几个问题只是为了帮助我澄清事情:

  1. @property是否重复或替换我的原始定义,还是只是设置了原始的可靠性和原子性?
  2. @synthesise是否删除了使用image = [[UIImageView alloc] init]
  3. 的需要
  4. 如果我没有提供@property并且仍然继续手动创建和销毁我的变量,那会有什么不同吗?
  5. 最终,是2之间的区别,@ property在内存管理和多线程方面为您提供了更大的灵活性,而正常的方法为您提供了默认值。

4 个答案:

答案 0 :(得分:3)

  

@prototype是复制还是替换我的原始定义,还是只是设置了原始的可靠性和原子性?

使用最新的编译器版本时,image的ivar声明是多余的

前者声明了一个ivar(类型+名称+实例存储)。

属性声明指定类型,名称,存储(在最近的编译器版本中),声明访问器方法(例如- (UIImageView *)image;- (void)setImage:(UIImageView *)pImage;),以及其他属性说明符(在访问器由编译器生成。

  

@synthesise是否删除了使用image = [UIImageView alloc]的需要?

没有。您仍然需要适当地实现初始化程序和dealloc(在MRC中)。

  

如果我不提供@property并且仍然继续手动创建和销毁我的变量,那会有什么不同吗?

如果您不希望/需要为您生成样板访问器方法,那就没问题了。这是一个设计选择。并非每个ivar都需要访问方法。

  

最终,是2之间的区别,@ property在内存管理和多线程方面为您提供了更大的灵活性,而正常的方法为您提供了默认值。

它们存在的最大原因是便利性。属性保存了很多样板代码。

属性没有更多灵活性 - 属性实现了最实际的用途。

很少见,原子性(在此上下文中)等同于正确的线程安全性和正确的并发执行。

答案 1 :(得分:2)

1)该属性不替换类成员。属性是一种声明,您希望访问者(getter和setter) 类成员执行某些“自动”任务并具有特定名称。

例如:

@interface MyClass : NSObject
{
    NSInteger __myInt;
}
@property (assign) NSInteger myInt;
@end

@implementation MyClass
    @synthesize myInt=__myInt;
@end

出于所有意图和目的,上述代码导致在编译时自动生成以下方法:

-(NSInteger) myInt
{
    return self->__myInt;
}
-(void) setmyInt:(NSInteger)val_
{
    self->__myInt = val_;
}

当然,当Xcode编译你的程序时,“在后台”发生的事情有点不同而且更加微妙,但这基本上就是发生的事情。

2)我并不完全清楚你的意思是什么......无论访问者是否合成,你总是需要allocinit你的变量。

3)否。属性/综合仅用于a)方便,无论是多线程的语法还是原子性,以及b)对类内成员的外部访问。

修改
为了阐明多线程和属性,声明属性nonatomic对线程安全起了很大作用。这个,以及我对#3的回答,解决了你在问题中的最后一个问题。

答案 2 :(得分:0)

你可以这样做:

 @interface MyClass : NSObject
 @property (retain, nonatomic) IBOutlet UIImageView *image;
 @end

 @implementation MyClass
 @synthesize image;
 @end
  

@prototype是复制还是替换我的原始定义,还是只是设置了原始的可靠性和原子性?

如果它是原子的,那么该属性就像在KVO和线程安全一样添加在ivar之上。

  

@synthesise是否删除了使用image = [UIImageView alloc]的需要?

没有

  

如果我不提供@property并且仍然继续手动创建和销毁我的变量,那会有什么不同吗?

如果你没有建造一个房产,你会失去一个属性让你像KVO一样的东西,这是对如何使用变量的判断和api调用。在弧线下,使用直线型ivars更容易,因为您不必复制保留并自动释放属性。

答案 3 :(得分:0)

@property中的'image'(保留,非原子)UIImageView *图像行只是属性的名称和IBOutlet UIImageView *图像;是一个通过self.image访问的ivar。我总是将名称的ivar命名为与名称相同的名称,但添加_:

UIImage * image_;
@property (retain, nonatomic) UIImageView *image;
@synthesize image = image_;

如果你不为你的财产创建一个ivar,Xcode会自动为你做(ivar的名称将与属性的名称相同)