Cen*_*ion 23 oop cocoa-touch properties objective-c ios
我有一些关于在工作中使用属性和实例变量的讨论,因此我想找到一个wiki的答案.现在,我知道在objective-c中没有真正的私有成员类型,一切都是公开的.但是,我有点担心我们应该如何设计我们的类以及遵守OOP原则.我想听听这三种设计方法的意见:
A.根据各种帖子甚至是新的斯坦福大学iPhone开发课程,你应该随时随地使用属性.然而恕我直言,这种方法制定了OOP设计原则,因为在这种情况下,所有成员都会公开.为什么我需要将所有内部/本地实例变量发布到外部?此外,如果您通过属性使用合成设置器,而不是直接使用本地ivar,则会有一些(但仍然)开销很小.这是一个示例:
//==== header file =====//
@interface MyClass : NSObject
@property (nonatomic, retain) NSString *publicMemberWithProperty;
@property (nonatomic, retain) NSString *propertyForPrivateMember;
@end
Run Code Online (Sandbox Code Playgroud)
B.另一种方法是在声明头文件的ivars(不宣相关性质)为私有成员,并且以相同的头文件,申报纯特性(不宣相对的ivars)为公众成员.在这种情况下,ivars将直接在课堂上使用.这种方法很有意义但不会使用属性的所有好处,因为我们在设置新值之前手动释放旧值.这是一个示例:
//==== header file =====//
@interface MyClass : NSObject{
NSString *_privateMember;
}
@property (nonatomic, retain) NSString *publicMemberWithProperty;
@end
Run Code Online (Sandbox Code Playgroud)
C.在头文件中为公共成员声明纯属性(不声明相对的ivars),并在实现文件的私有接口中为私有成员声明纯属性(不声明相对的ivars).这种方法恕我直言比第一种更明确,但同样的问题仍然存在:为什么我们必须拥有内部/本地成员的财产?这是一个示例:
//==== header file =====//
@interface MyClass : NSObject
@property (nonatomic, retain) NSString *publicMemberWithProperty;
@end
//==== implementation file =====//
@interface MyClass()
@property (nonatomic, retain) NSString *propertyForPrivateMember;
@end
Run Code Online (Sandbox Code Playgroud)
这个决定的自由让我感到很恼火,我想从各自的消息来源中找到关于应该如何做的确认.但是,我无法在Apple文档中找到这样严格的声明,所以请发布一个链接到Apple docs(如果有的话),或者发布任何其他清除它的理论.
Vik*_*ica 21
通过使用类扩展,您可以拥有私有属性.
类扩展语法很简单:
在具有该类的.m文件中,创建一个未命名的类别:
.H
@interface OverlayViewController : UIViewController <VSClickWheelViewDelegate>
- (IBAction)moreButtonClicked:(id)sender;
- (IBAction)cancelButtonClicked:(id)sender;
@end
Run Code Online (Sandbox Code Playgroud)
.M
#import "OverlayViewController.h"
@interface OverlayViewController ()
@property(nonatomic) NSInteger amount;
@property(retain,nonatomic)NSArray *colors;
@end
@implementation OverlayViewController
@synthesize amount = amount_;
@synthesize colors = colors_;
//…
@end
Run Code Online (Sandbox Code Playgroud)
现在,您可以获得私有成员的所有属性,而不会将其暴露给公众.写入getter/setter的合成属性应该没有开销,因为编译器在编译时会创建或多或少的相同内容.
请注意,此代码使用合成的ivars.标题中不需要ivar声明.
关于这种方法,有一篇很好的cocoawithlove文章.
您还会问为什么要使用私有ivars的属性.有几个很好的理由:
编辑
从LLVM 3开始,也可以在类扩展中声明ivars
@interface OverlayViewController (){
NSInteger amount;
NSArray *colors;
}
@end
Run Code Online (Sandbox Code Playgroud)
甚至在实施区块
@implementation OverlayViewController{
NSInteger amount;
NSArray *colors;
}
//…
@end
Run Code Online (Sandbox Code Playgroud)
参见"WWDC2011:会议322 - Objective-C深度进展"(~03:00)