Objective-C : Need advice on setting instance variables in init method

标签 objective-c ios ios5 getter-setter

我正在使用 ARC。

这是我的 .h 文件

...
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
...

这是我的 .m 文件
....
@synthesize coordinate, title;

- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
    self = [super init];
    if (self) {
        coordinate = c;
        [self setTitle:t];
     }
    return self;
}
....
  • 以这种方式设置坐标,正确的方法吗?鉴于我将其声明为 readonly ,似乎这是唯一的方法。如果我只使用默认值(即 readwrite )怎么办,在这种情况下,我应该改用 setter 方法 [self setCoordinate] 吗?
  • 我可以通过 title = t 设置标题也是。与使用setter方法相比,结果是一样的,但有什么区别呢?


  • 谢谢!希望我能接受你所有的答案。

    最佳答案

    您实际上应该一直直接在初始化方法中设置 ivars。无论您是否拥有 readonly,这都是正确的。或 readwrite属性(property)。 documentation here甚至这么说。

    这背后的原因与继承有关。如果有人要对您的类进行子类化并覆盖您的属性的 setter ,以便他们绕过您创建的 ivars(或做一些其他古怪的事情),那么突然之间,您的初始化方法的原始实现现在不再执行其编写的操作.特别是,由于子类覆盖了您的访问器,您的初始化程序最终可能会创建一个具有奇怪状态的对象。在 ARC 之前的日子里,当这种事情发生时,你也可能会遇到棘手的(或者只是直接坏掉的)内存情况。要点是:您应该编写初始化程序,以便它们始终创建具有已知有效状态的对象。

    因此(假设您使用的是 ARC)您的初始化程序实际上应该是:

    - (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
    {
        self = [super init];
        if (self) {
            coordinate = c;
            title = [t copy];
         }
        return self;
    }
    

    就个人而言,我更喜欢用下划线开始合成 ivars,以澄清我何时使用该属性以及何时直接访问该 ivar(LLVM 4.0 现在也这样做以自动合成属性)。
    @synthesize coordinate = _coordinate;
    @synthesize title = _title;
    
    - (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
    {
        self = [super init];
        if (self) {
            _coordinate = c;
            _title = [t copy];
         }
        return self;
    }
    

    关于 Objective-C : Need advice on setting instance variables in init method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13104172/

    相关文章:

    iphone - 清除 UIImage 上的绘图?

    objective-c - 在 Facebook 照片上传中标记 friend

    objective-c - 可访问性标签 storekit 用户输入

    ios - 重新创建 messages.app 图像选择器有多难

    ios - UIImagePickerController Camera Overlay 匹配默认裁剪

    ios - iPhone/iPad 壁纸图像 monotuch

    ios - 将 UIVisualEffectView 添加到 UITableView 的背景 View 仅适用于模拟器而非设备

    ios - 像 UIPopoverController 这样的自定义 UIView

    iphone - 重命名 Settings.bundle 而不是 Bundle 显示名称?

    ios - 根据音乐点亮