【问题标题】:Getters/Setters for NSObjectNSObject 的 Getter/Setter
【发布时间】:2013-08-26 00:24:55
【问题描述】:

这是我第一次尝试创建一个对象来存储我的数据并且遇到了一些麻烦。我不确定我的做法是否正确。

歌曲.h:

#import <Foundation/Foundation.h>

@interface Song : NSObject{
    NSString *songID;
    NSString *title;
    NSString *artist;
    NSString *album;
    NSString *length;
    NSString *votes;
}
-(void)setSongID:(NSString*) p_songId;
-(void)settitle:(NSString*) p_title;
-(void)setartist:(NSString*)p_artist;
-(void)setalbum:(NSString*) p_album;
-(void)setlength:(NSString*) p_length;
-(void)setvotes:(NSString*) p_votes;

-(NSString*)getSongID;
-(NSString*)gettitle;
-(NSString*)getartist;
-(NSString*)getalbum;
-(NSString*)getlength;
-(NSString*)getvotes;

@end

歌曲.m

#import "Song.h"

@implementation Song


-(void)setSongID:(NSString*) p_songId;{

}
-(void)settitle:(NSString*) p_title{

}

-(void)setartist:(NSString*)p_artist{

}
-(void)setalbum:(NSString*) p_album{

}
-(void)setlength:(NSString*) p_length{

}
-(void)setvotes:(NSString*) p_votes{

}

-(NSString*)getSongID{

}
-(NSString*)gettitle{

}
-(NSString*)getartist{

}
-(NSString*)getalbum{

}
-(NSString*)getlength{

}
-(NSString*)getvotes{

}

@end

我的实现文件看不到任何变量,例如我不能用self.songID = p_songID设置songID

objective-c 是否有处理这些 setter/getter 的内置方式,我是不是走错了路?

【问题讨论】:

  • 您没有将符号声明为“属性”,因此您不能使用self. 符号来解决它们。相反,您必须像在 C++ 中那样使用 self -&gt; 来处理实例字段。我知道这很令人困惑。
  • 如果您使用属性,请务必了解编译器“在幕后”生成您想要的 getter/setter。

标签: ios objective-c nsobject


【解决方案1】:

Objective C 有一种方法可以为您设置 getter 和 setter,这样您就不必担心自己编写它们。它通过属性来做到这一点。要设置属性,请在头文件中写入

@property (strong, nonatomic) NSString *songID;

通常,除非您有理由不这样做,否则您将使用强和非原子修饰符。如果您有兴趣,可以研究其他参数。写完该行之后,将为您生成 getter 和 setter。

要在类中使用此属性,您只需使用点表示法和 self 对象。例如,要设置值,您可以编写

self.songID = @"66777888";

您以相同的方式访问属性的值。例如,要分配另一个等于该值的字符串,您可以编写

NSString *other = self.songID; 

如果你想在子类之外访问这些值,你仍然使用点表示法,除了现在使用类的实例。例如,如果你想设置另一个类的songID,你可以写

Song *song = [[Song alloc] init];
song.songID = @"790";

【讨论】:

  • 应该注意的是,NSString(有时是NSArray 属性)通常应该使用copy 标识符而不是strong
  • 感谢 Erik 并感谢 Rickay 提供的信息,现在正在阅读所有不同的属性。
  • 我还要注意,如果您使用 ARC 并启用了自动合成属性,编译器会直接使属性后面的实例变量可用,并带有下划线前缀。您可以访问或设置 songID 的值,例如:_songID = value 我更喜欢这样区分内部属性
  • 是的,虽然这是一个选项,但你真的应该只在覆盖 getter 或 setter 时才使用它。
  • 我不同意。使用 ARC 时,在内部使用 self.* 没有任何优势(就像在 MRC 下一样)。我现在几乎完全采用这种方式,因为这样可以更清楚地区分访问我自己的数据和另一个对象的数据。
【解决方案2】:

objective-c 是否有处理这些 setter/getter 的内置方式,我是不是走错了路?

是的,Objective-C 有自己的方式:@property

你只想声明一个这样的属性:

@interface Song : NSObject
@property (strong, nonatomic) NSString * songID;
@end;

这将自动生成:

- (void)setSongID:(NSString *)songID;
- (NSString *)songID;

所以你不必自己写。

顺便说一句,strong 表示您想拥有该对象,它是您的。 而nonatomic 是关于线程安全的。

【讨论】:

    【解决方案3】:

    你可以简单地把你的类写成

    @interface Song : NSObject
    
    @property (strong, nonatomic) NSString *songID;
    @property (strong, nonatomic) NSString *title;
    @property (strong, nonatomic) NSString *artist;
    @property (strong, nonatomic) NSString *album;
    @property (strong, nonatomic) NSString *length;
    @property (strong, nonatomic) NSString *votes;
    
    @end
    

    成员变量和 getter/setter 由编译器生成。 如果您不想要成员的 setter,那么您将使用 readonly 说明符:

    @property (strong, nonatomic, readonly) songID;
    

    如果您需要特殊处理,您只需要手动提供 getter 或 setter 的实现。只是一个人为的例子:

    @implementation Song
    
    void setTitle:(NSString*)title
    {
        if (some conditions)
            self.votes = @"winner";
    
        self.title = title;
    }
    
    @end
    

    让编译器生成 getter 和 setter 不仅可以节省您无聊的打字时间并创建更简洁的代码,还可以处理同步和引用计数问题。但它并不适用于所有情况。这些是生成原子属性和/或不使用 ARC 时需要担心的事情。

    这里注意到编译器通过在属性前加下划线来为你生成成员变量。例如。 _songID 或 _title 等。在类实现中,您可以访问和设置变量,如

    self.title = @"title";
    _title = @"title";
    

    哪个合适? self.title - 在大多数情况下,_title - 在某些情况下。如果适用,请记住非 ARC 代码和原子实现。

    如果你想让你的属性只能从你的类(又名私有成员)访问,那么使用类扩展。在您的实现 .m 文件中:

    @interface Song()
    @property (strong, nonatomic) foo;
    @end
    
    @implementation Song
    ...
    @end
    

    为了完整起见,我要补充一点,您只能将 getter 或 setter 设为“私有”。

    【讨论】:

    • s/是/可以是/。您仍然需要 @synthesize 实现部分中的属性,以便编译器生成 getter、setter 和支持变量。
    • @cHao:不,编译器现在在很多情况下会automatically synthesize
    • @KurtRevis:好的,现在这很简单。 :) 他们正在删除越来越多的样板废话,这很好。
    【解决方案4】:

    访问器方法的命名约定是 getter 可能与属性具有相同的名称,对于布尔属性,以 is 为前缀。它们不应以get 为前缀。并且 setter 以 set 前缀命名,后跟 大写 属性名称。

    所以,你可能有:

    - (NSString*) title;
    - (void) setTitle:(NSString*)newTitle;
    

    等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2017-11-22
      • 1970-01-01
      • 2010-11-13
      • 2021-10-17
      相关资源
      最近更新 更多