Objective c 为什么要将一些实例变量声明为属性

Objective c 为什么要将一些实例变量声明为属性,objective-c,properties,Objective C,Properties,虽然这是一个非常基本的问题,但在阅读了stackoverflow.com上的大量文档和问题后,我仍然有一些疑问 我想知道为什么要将一些实例变量声明为属性 MYViewController.h @interface MyViewController : UIViewController { UIButton *btn; NSString *name; } @property (nonatomic, retain) UIButton *btn;

虽然这是一个非常基本的问题,但在阅读了stackoverflow.com上的大量文档和问题后,我仍然有一些疑问

我想知道为什么要将一些实例变量声明为属性

MYViewController.h
   @interface MyViewController : UIViewController {
        UIButton *btn;
        NSString *name;
    }
    @property (nonatomic, retain) UIButton *btn;
    @property (nonatomic, retain) NSString *name;

MyViewController.m
   @implementation MyViewController
   @synthesize btn;

-(void) viewDidLoad()
{
   [btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is first way where there is no need to declare btn as property

   [self.btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is second way where we do need to decalre btn as property as we are accessing it through self 


//Setting value of name

  name = @"abc"; //this is first way where there is no need to declare name as property 
  [self setName:@"abc"; //this is second way where we do need to declare name as property as we are accessing its aetter method through self

}
现在在上面的代码中,我想知道什么时候我们可以使用btn变量的getter/setter方法而不将其声明为属性,那么需要将其声明为属性,以及设置“name”值的更好方法是什么

我在某个地方读到,当您希望您的实例变量被我的其他类对象访问时,您应该将它们声明为实例变量。这是我们应该将它们声明为属性的唯一情况

MYViewController.h
   @interface MyViewController : UIViewController {
        UIButton *btn;
        NSString *name;
    }
    @property (nonatomic, retain) UIButton *btn;
    @property (nonatomic, retain) NSString *name;

MyViewController.m
   @implementation MyViewController
   @synthesize btn;

-(void) viewDidLoad()
{
   [btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is first way where there is no need to declare btn as property

   [self.btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is second way where we do need to decalre btn as property as we are accessing it through self 


//Setting value of name

  name = @"abc"; //this is first way where there is no need to declare name as property 
  [self setName:@"abc"; //this is second way where we do need to declare name as property as we are accessing its aetter method through self

}
基本上,我对在哪些情况下将实例变量声明为属性有点困惑

MYViewController.h
   @interface MyViewController : UIViewController {
        UIButton *btn;
        NSString *name;
    }
    @property (nonatomic, retain) UIButton *btn;
    @property (nonatomic, retain) NSString *name;

MyViewController.m
   @implementation MyViewController
   @synthesize btn;

-(void) viewDidLoad()
{
   [btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is first way where there is no need to declare btn as property

   [self.btn setTitle:@"Hello" forState:UIControlstaeNormal]; //this is second way where we do need to decalre btn as property as we are accessing it through self 


//Setting value of name

  name = @"abc"; //this is first way where there is no need to declare name as property 
  [self setName:@"abc"; //this is second way where we do need to declare name as property as we are accessing its aetter method through self

}
请建议。
提前感谢。

简而言之,除非您愿意,否则您不必将实例变量声明为属性。 将变量声明为属性,以便自动生成getter和setter方法。在属性声明中,您可以指定如何设置它们(保留vs分配,原子vs非原子)。然后,使用@synthesis指令生成getter和setter。
因此,再次强调,使用属性没有正确或错误的方法。有些人从不使用它们,有些人把每个变量都当作属性。这真的取决于你

通常,您会使用它们,因为:

1) 该属性属于类的公共接口

当类需要公开给定的方法时使用。缺点是客户机和子类可能会滥用公共接口(所有objc方法都是公共的,如果可见的话),除非您小心地隐藏这些细节(有时这也是一个难题)。有时,为了实现所需的类接口(具有适当的可视性级别),您不得不非常小心

2) 您需要自动生成的访问器

实现非专用的访问器非常繁琐,而且容易出错。最好节省时间,让编译器为您生成它们

3) 记录行为

有时最好编写
@property(copy)NSString*title而不是过度记录预期结果

4) 使用点语法进行更严格的选择器匹配

编译器执行更严格的选择器匹配。如果可能,更愿意在编译时捕获错误/问题

5) 强制子类使用它们,而不是直接处理IVAR

默认情况下,objc IVAR受保护。您通常希望它们是私有的(取决于类的使用和分布方式,或者只是为了确保子类正确使用基类)

原因有很多。线程和维护是最重要的

如果您将ivar声明为私有,并为子类提供要使用的属性,那么子类将被迫在其实现中使用该属性(尽管存在欺骗的方式),而不是让它们直接访问ivar


所以。。。它最终取决于您的偏好、类的实现细节以及您正在使用的接口。我不认为这里有一个硬性规定——较小的罪恶和便利是主要的动机。

Thanx,请参阅您的详细帖子。我真的很感激,但请你更具体地回答我的问题,基本上是我问题中的两个例子所带来的困惑。@Kiara,不客气。当然-有了这个澄清,我认为您最感兴趣的是如何访问和设置实例变量,给定viewDidLoad示例中的上下文。(
@property(nonatomic,retain)UIButton*btn;
(cont)5)您没有使用部分解构的实例6)该方法被重写并且可能被重新重写——在这种情况下,我将通过属性访问,因此我认为使用[self.btn setTitle:@“Hello”for state:UIControlStateNormal]是一种更好的方法;凯拉:答案写在我之前的评论中。答案是“是的,使用访问器”