【问题标题】:Difference between variables in interface Object() {} and @implementation Object @end接口 Object() {} 和 @implementation Object @end 中的变量之间的区别
【发布时间】:2014-09-23 03:05:21
【问题描述】:

我从 Objective-CiOS 开始我的冒险,但我有一件事情我不知道如何正确使用,这简直让我大吃一惊。

许多教程在.m 文件中都有私有类变量,定义如下:

@interface ViewController (){
    @property (nonatomic, strong) NSMutableArray *myArray;
}

或者像这样:

@implementation ViewController
        NSMutableArray *myArray;
@end

在第一个示例中,我可以使用_myArray 而不是我喜欢的self.myArray,但是我应该将所有私有变量都放在接口文件中吗?这两个变量有什么区别?什么时候应该使用一个而不是另一个,哪个更安全?

【问题讨论】:

标签: ios objective-c


【解决方案1】:

@property 创建您的 setter,而另一个则没有。

【讨论】:

  • 这是唯一的区别吗?为什么要在包含这些变量的类中使用 setter 和 getter?
  • 属性很有用,当你想在两个视图控制器之间传输值时
  • 是的,我知道,但是当我想在控制器之间传输值时,我将它们放在 .h 文件中而不是 .m 文件中
【解决方案2】:

不同的是:

  • _myArray 是实例变量。

  • self.myArray 正在您的对象上调用 getter 方法。

  • 使用self.myArray = nil 使变量通过其设置器,因此在使用ARC时释放对象。

    • 如果属性声明为 atomic(默认值),这意味着访问该变量是线程安全的,但会降低性能
    • nonatomic 属性表示从多个线程访问变量或属性时可能会发生竞争条件。

一般来说,atomic 用于与多个线程共享的对象,nonatomic 用于 UI 或非共享对象。

【讨论】:

  • 第三点毫无意义。对于atomic 财产,有点对吗?出于不同的原因。对于 nonatomic 属性(这是 OP 要求的),它们几乎相同,除非 setter 被覆盖并且不会发生内存泄漏(不考虑竞争条件)。
  • @iBhavin - 是的,atomic 不能确保线程安全,尤其是对于可变数组(not thread-safe)之类的东西。 atomic 只是确保指针在被另一个线程访问时不能被一个线程改变,但不保证它指向的对象。它在处理基本数据类型时很有用,但除此之外几乎没有什么实际用途。
【解决方案3】:

是的,@property 会自动创建 setter 和 getter。

此外,您可以设置属性的属性。 (只读/读写,非原子/原子,强/弱..等)

通过getter和setter访问实例变量(而不是使用指针直接访问)使数据封装。

这是面向对象编程的常见且重要的概念。

阅读本文以了解。

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

抱歉英语不好。 :

【讨论】:

    【解决方案4】:

    注意,您的代码会出现编译器错误:

    @interface ViewController (){
        @property (nonatomic, strong) NSMutableArray *myArray;
    }
    

    -> 您必须将 @property... 移到标题的 {} 之外。

    @interface ViewController (){
        //
    }
    
    @property (nonatomic, strong) NSMutableArray *myArray;
    

    【讨论】:

      【解决方案5】:

      一些想法:

      1. 第一个示例在语法上不正确。您可能指的是以下内容,它在class extension 内定义了一个declared property

        @interface ViewController ()
        @property (nonatomic, strong) NSMutableArray *myArray;
        @end
        

        房产将:

        • 合成一个名为_myArray的实例变量(或者如果你指定了@synthesize指令,你可以控制这个实例变量的名字);

        • 合成访问器方法,特别是检索值的myArray getter 和设置值的setMyArray setter;

        • 提供key-value coding等其他功能

      2. 另一方面,以下声明了一个全局变量:

        @implementation ViewController
        NSMutableArray *myArray;
        @end
        

        全局变量是一个非常不同的野兽,在这个类的所有不同实例之间共享(以及在整个应用程序中)。在这种情况下(类实例使用的一些可变数组),全局变量可能不是您想要的。

      3. 如果你打算定义一个实例变量,你可以这样做:

        @implementation ViewController
        {
            NSMutableArray *myArray;
        }
        @end
        

        或者,也许比在 @implementation 中定义这个 ivar 更好,通常会在类扩展的 @interface 中定义它们:

        @interface ViewController ()
        {
            NSMutableArray *myArray;
        }
        @end
        

      我怀疑您实际上并不打算将全局变量与实例变量 (ivar) 或属性进行比较,而是询问在类实现中私下使用属性与 ivar 的基本原理:

      归根结底,在特定类中,使用 ivars 是一种完全可以接受的做法,但我们中的许多人使用在类扩展中定义的私有属性。开销是最小的,它将代码从 ivar 的实现细节中抽象出来。例如,您可以在将来的某个日期自定义一个或多个访问器方法,并且对类实现的其余部分影响最小。但这是个人喜好问题。

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2010-11-28
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        • 2016-02-09
        • 2019-04-25
        • 2010-11-04
        相关资源
        最近更新 更多