【问题标题】:Objective C Semi Readonly propertyObjective C 半只读属性
【发布时间】:2014-09-09 13:25:41
【问题描述】:

我想在我的class 中声明一个public NSString property,它在我的课堂外充当readonly property,但我可以在我的课堂内使用assign 任何值。我怎样才能实现这种行为。

【问题讨论】:

    标签: ios objective-c properties readonly


    【解决方案1】:

    您必须像这样在.h 文件中声明您的属性

    @interface MyClass : NSObject
    
    @property (strong, nonatomic, readonly) NSString *aString;
    
    @end
    

    但是在你的.m 文件中你必须有

    @interface MyClass () // your anonymous category
    
    @property (strong, nonatomic, readwrite) NSString *aString;
    
    @end
    
    @implementation MyClass
    
    @end
    

    在外部aStringreadonly,在内部你可以设置值(readwrite)

    您通过实现anonymous category also known as class extension in Objective-C 来实现它

    【讨论】:

    • @Injectios 不,问题是关于 NSString 的,我的回答包含不同的解释。重要的是关键字private category,提问者可以在其中进一步了解它。
    • 你的NSStrings 没有正确声明——它们应该是指针。
    • 正确的术语是class extension。 “匿名类别”几乎一样好,但“私人类别”是错误的。它并不比任何其他类别更私密。
    • @JeremyP 感谢您通知我。我已经完成了更正。但是private category这个词已经在stackoverflow的答案和一些高级的Objc书籍中广泛使用。
    • 仍然使用术语“匿名类别”,而苹果使用的官方术语是:“类扩展”。来自 Apple 文档:“类扩展与类别有一些相似之处,但它只能添加到您在编译时拥有源代码的类中。”
    【解决方案2】:

    在标头中将属性定义为readonly,并在class extension 的实现文件中将其声明为readWrite。该属性在类实现之外是只读的,在实现中是读/写的。

    // Interface file:
    @interface Test : NSObject
    @property (nonatomic, copy, readonly) NSString *propertyString;
    @end
    
    // Implementation file:
    @interface Test () // Class Extension
    @property (nonatomic, copy, readwrite) NSString *propertyString;
    @end
    
    @implementation Test
    @end
    

    见:Use Class Extensions to Hide Private Information

    正如@Amin Negm-Awad 在回答中指出的那样:接口和类扩展不需要在接口或实现文件中,尽管这是通常的用法。

    【讨论】:

      【解决方案3】:

      .h文件中添加:

      @property(nonatomic,readonly)NSString* property;
      

      .m文件中添加:

      @interface yourClass ()
      
      @property(nonatomic,readwrite)NSString* property;
      
      @end
      

      【讨论】:

        【解决方案4】:

        在头文件(接口)中将属性定义为只读,在实现文件中定义为读写。这也使您可以轻松地使其变弱/变强/复制。

        【讨论】:

        • 具有部分定义的只读属性和完全定义的读写属性的行为最近发生了变化。没有定义任何行为。最好的做法是,在 readonly 定义中定义包含在 readwrite 定义中的属性的所有属性。
        【解决方案5】:

        这可能很明显:

        在您的 .h 文件中将属性声明为 readonly

        @property (nonatomic, assign, readonly, getter = isLoading) BOOL loading;
        

        在您的 .m 文件中将属性声明为 readwrite

        @property (nonatomic, assign, readwrite, getter = isLoading) BOOL loading;
        

        这是一个例子,显然你应该创建强大的NSString 属性,并且我假设编译器不允许在类之外设置其他值,但在它内部会。

        【讨论】:

          【解决方案6】:

          除了告诉您定义只读属性并将其更改为读写属性的现有答案之外,这是完全正确的预期模式(即读写的用途),我想添加一个可能重要的信息:

          您将只读定义放在接口中。 (不是标题!)

          您将读写定义放在类延续中。 (不是实现文件)

          有人可能会说这是一样的,因为接口驻留在头文件中,而类延续驻留在实现文件中。但这只是通常的情况。

          您还可以将类延续放在第三个文件中。然后像“朋友类”这样的东西可以额外导入它,这个“炒类”有写访问权。在开发框架时,我经常这样做。

          MyClass.h: // 公共标头,所有人都可以使用

          @interface MyClass : NSObject
          @property (readonly, …) id property1; // Everyone can read it
          @property (readonly, …) id property2; // Everyone can read it
          - (void)method; // Everyone can use it
          @end
          

          MyClass_Package.h: // 项目头,框架类可用,框架用户不可用

          @interface MyClass()
          @property (readwrite, …) id property1; // All classes inside the framework can write it
          - (void)packageMethod;                 // All classes inside the framework can use it
          @end
          

          MyClass.m

          @interface MyClass() // A second class extension inside .m
          @property (readwrite, …) id property2; // Only MyClass can write it
          - (void)privateMethod;                 // Only MyClass can use it
          @end
          

          【讨论】:

          • 由于这篇文章主要是迂腐的,所以是Class Extension而不是class continuation
          • 1.没有。这篇文章主要不是迂腐,而是新引入了一种在其他编程语言中称为友谊的模式。 (并且在 Objective-C 中已经知道 ivars。) 2. 不,有时它被称为类延续,有时被称为类扩展。类延续是更好的术语,因为类别也是类扩展。 (并且在某种程度上是子类。)
          • 常规类别不是类扩展。两者有不同的用途和功能。请参阅前面评论中的链接。根据 Apple 文档:“类别向现有类添加方法”,而“类扩展扩展内部实现”。 “与常规类别不同,类扩展可以将自己的属性和实例变量添加到类中。”
          • 我知道类扩展和类别(正式)是什么。但是类别满足(非正式)术语“类扩展”的含义。他们扩展类。因此,对于(正式的)类扩展,我更喜欢术语类延续,因为不存在误解的危险。
          【解决方案7】:

          在头部定义属性为readonly,并使用下划线语法设置。

          @property (nonatomic, readonly) NSString *myString;
          
          - (void)someMethodInYourDotMFile {
              _myString = YES;
          }
          

          【讨论】:

            猜你喜欢
            • 2011-06-02
            • 1970-01-01
            • 2015-08-14
            • 1970-01-01
            • 2012-12-25
            • 2011-07-09
            • 1970-01-01
            • 1970-01-01
            • 2014-08-22
            相关资源
            最近更新 更多