我花了几天时间学习Objective-C,并对@property
提出了一些问题。我有使用C#的经验,所以理解需要指针,初始化等。
以此为例:
@interface MyClass : NSObject
{
IBOutlet UIImageView *image;
}
@property (retain, nonatomic) UIImageView *image
@end
@implementation MyClass
@synthesise image
@end
我了解@synthesise
用于创建@property
。但是我有几个问题只是为了帮助我澄清事情:
@property
是否重复或替换我的原始定义,还是只是设置了原始的可靠性和原子性?@synthesise
是否删除了使用image = [[UIImageView alloc] init]
?@property
并且仍然继续手动创建和销毁我的变量,那会有什么不同吗?最终,是2之间的区别,@ property在内存管理和多线程方面为您提供了更大的灵活性,而正常的方法为您提供了默认值。
答案 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)我并不完全清楚你的意思是什么......无论访问者是否合成,你总是需要alloc
和init
你的变量。
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的名称将与属性的名称相同)