如果我用Objective-C 中的只读属性替换我的所有访问器(get-like const 方法),有什么缺点吗?它们可以互换吗?
我更喜欢文档/可读性的只读属性。
来自 C++,我正在考虑用ObjC 中的只读属性替换我的所有 const 方法(非可变方法)。
如果我遵守这个约定,那么我可以自动假设任何常规方法都会改变状态(C++ 中的非常量方法)。同样从函数式编程的角度来看,知道只读属性不会改变任何状态(没有副作用)是有用的。
如果我用Objective-C 中的只读属性替换我的所有访问器(get-like const 方法),有什么缺点吗?它们可以互换吗?
我更喜欢文档/可读性的只读属性。
来自 C++,我正在考虑用ObjC 中的只读属性替换我的所有 const 方法(非可变方法)。
如果我遵守这个约定,那么我可以自动假设任何常规方法都会改变状态(C++ 中的非常量方法)。同样从函数式编程的角度来看,知道只读属性不会改变任何状态(没有副作用)是有用的。
是的,当然——如果您愿意,也可以采用这种方式实现。从上下文来看,这样做有很多潜在的好处。
需要注意的缺点是生成属性的成本——它们可能会慢 20 倍以上。如果(例如)您的财产不可重新分配,那么执行所有参考计数循环/自动释放活动是一种巨大的浪费。
另一个(次要)缺点是您会经常发现自己实现或声明私有设置器。
可以以相同的方式访问它们(点语法或方法语法)。做任何感觉最好的事情。尽管我更喜欢将方法作为方法,但当它们执行(某些)逻辑时。如果它只是一个返回一些数据的访问器/获取器,那么属性更适合。
这与键值编码有关。采取以下措施:
@interface Boat : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end
和...
@interface Boat
@synthesize name;
@end
合成器所做的(在这种情况下)是创建两种方法:
-(NSString *)name;
-(void)setName;
它使用所谓的“驼峰式”命名选择器,将 ivar 的第一个字母更改为大写字母,然后将“set”添加到 setter 的前面。getter 的名称只是 ivar 的名称。
如果您的 ivar 名称和现有方法遵循此模式,那么用属性替换您的手写访问器将完美无缺,无论您使用点语法还是显式消息:
boat.name = @"Pequod"
编译为[boat setName:@"Pequod"]
. 并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,则不需要包含 @synthesize 语句。否则你会写:@synthesize myStr = _myStr;
在实现文件中。
您仍然需要一些方法来设置它们,并且拥有一个合适的设置器对于自动化内存管理目的通常非常方便。创建类扩展正是为了实现这个目的;公开只读,私人读写。
富.h:
@interface Foo : NSObject
@property(readonly, copy) NSString* bar;
@end
Foo.m: @interface Foo() @property(readwrite, copy) NSString* bar; @结尾
@implementation Foo
... no need to @synthesize ...
- randomMethod
{ [self setBar:@"bas"]; ... self.bar; _bar = [NSString stringWithFormat:@"%@ %@", [self bar], self.bar]]; }
是的,你想要copy
@interface 声明中的。接口中的修饰符,即使是只读属性,也可以修改 getter 和 setter 的 codegen。
你可能会发现我对这个问题的回答也很相关。