Objective c 目标C:是否可以用只读属性替换所有访问器?

Objective c 目标C:是否可以用只读属性替换所有访问器?,objective-c,properties,styles,Objective C,Properties,Styles,如果我用Objective-C中的只读属性替换所有访问器(像const方法一样获取),有什么缺点吗?它们可以互换吗 对于文档/可读性,我更喜欢只读属性 来自C++,我想用Objc中的 >只读属性>替换所有的const方法(非可变方法)。 如果我遵守这个约定,那么我可以自动假设任何常规方法都将改变状态(C++中的非常量方法)。同样从函数式编程的角度来看,知道只读属性不会改变任何状态(没有副作用)也是很有用的。它们可以以相同的方式访问(点语法或方法语法)。做感觉最好的事。虽然我更喜欢将方法作为方法,

如果我用Objective-C中的只读属性替换所有访问器(像const方法一样获取),有什么缺点吗?它们可以互换吗

对于文档/可读性,我更喜欢只读属性

来自C++,我想用Objc中的<强> >只读属性>替换所有的const方法(非可变方法)。


如果我遵守这个约定,那么我可以自动假设任何常规方法都将改变状态(C++中的非常量方法)。同样从函数式编程的角度来看,知道只读属性不会改变任何状态(没有副作用)也是很有用的。

它们可以以相同的方式访问(点语法或方法语法)。做感觉最好的事。虽然我更喜欢将方法作为方法,但当它们执行(某些)逻辑时。如果只是一个访问器/获取器返回一些数据,那么属性就更合适。

这与。采取以下行动:

@interface Boat : NSObject {
   NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end
而且

@interface Boat
@synthesize name;
@end
合成器所做的(在本例中)是创建两种方法:

-(NSString *)name;
-(void)setName;
它使用所谓的“驼峰格”命名选择器,将ivar的第一个字母改为大写,然后在setter前面添加“set”。getter的名称就是ivar的名称

如果您的ivar名称和现有方法遵循此模式,那么无论您使用的是点语法还是显式消息,用属性替换手写的访问器都可以完美地工作:

boat.name=@“peqood”
被编译为
[boat setName:@“peqood”]
。而
boat.name
被编译成
[boat name]


如果您的访问器没有这样命名,那么您将需要在代码中修改使用它们来匹配此模式的位置。按照这种模式编码是所有Objective-C/Cocoa编程的最佳方法。

是的,它们是可交换的

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

@interface MyClass : NSObject
-(NSString *)myStr;
@end
@interface MyClass() { NSString *_myStr } 
@end
@implementation MyClass
-(NSString *)myStr { return _myStr; }
@end
虽然在代码中看不到它,但属性确实创建了一个可访问的myStr方法。在这两种情况下,您都可以使用
self.myStr
[self-myStr]
调用该方法

旁注:如果您使用的是iOS 6,则不需要包含@synthesis语句。否则您将编写:
@synthesis myStr=\u myStr在实现文件中。

是的,当然——如果您愿意,可以这样处理实现。从上下文来看,这样做可能有很多好处

要注意的缺点是生成属性的成本——它们可能超过。如果(例如)您的属性不可重新分配,那么执行所有引用计数循环/自动释放活动将是巨大的浪费


另一个(次要)缺点是,您经常会发现自己实现或声明私有setter。

您仍然需要一些方法来设置它们,而拥有一个合适的setter对于自动化内存管理目的来说通常非常方便。创建类扩展就是为了实现这个目的;公开只读,私下读写

Foo.h:

@interface Foo : NSObject
@property(readonly, copy) NSString* bar;
@end
Foo.m: @接口Foo() @属性(读写、复制)NSString*条; @结束

{ [自我挫折:@“bas”]; …自我酒吧; _bar=[NSString stringWithFormat:@“%@%@”,[self-bar],self.bar]]; }

是的,您需要@interface声明中的
副本。接口中的修饰符,即使在只读属性上,也可以修改getter和setter的codegen


你很可能也很相关。

你是在谈论属性还是方法?这个问题似乎有点令人困惑。你能提供一个你想要实现的代码示例吗?@Anurag-在标准OOP术语中,访问器是一个常量、不可变的get-like方法。对我来说,它似乎类似于一个只读属性——这就是我为什么要发布这个问题的原因。+1代表一个好的观点(点语法或方法语法)。我更喜欢将实现隐藏到消费者不知道逻辑是否必要的地步——但有时,消费者知道调用是否会改变对象是很有用的。改变对象的只读属性真的很奇怪,不是吗?无法想到用例。但我同意,财产访问有时可能涉及一些逻辑。但这实际上取决于用例。那么你想在这里回答什么呢?你有明确的例子吗?@Jayde3 lazy initialization是一个经常使用的例子。@justin:当然有。。但这不符合逻辑。而且它不是改变对象本身,而是创建一个成员。这是逻辑。好啊但没有真正的自我突变。只是给它添加图像。嗯。。你可以把它算作突变。现在不那么重要了。:)
@implementation Foo
... no need to @synthesize ...
- randomMethod