一般编程有关属性,赋值,保留和声明的问题

时间:2011-01-10 20:21:00

标签: iphone objective-c

我正在通过WWDC的AVCam项目,我对以下代码感到好奇。我以为你应该声明一个对象,然后@property(非原子,保留),然后合成。

演示代码有点不同,我会发布一些代码(只是一个示例),任何人都知道这是什么以及何时应该使用它?谁能解释它的意义以及何时使用它?

    @interface AVCamCaptureManager : NSObject {
@private
    // Capture Session
    AVCaptureSession *_session;
    AVCaptureVideoOrientation _orientation;

    // Identifiers for connect/disconnect notifications
    id _deviceConnectedObserver;
    id _deviceDisconnectedObserver;
}

@property (nonatomic,readonly,retain) AVCaptureSession *session;
@property (nonatomic,assign) AVCaptureVideoOrientation orientation;
@property (nonatomic,readonly,retain) AVCaptureAudioChannel *audioChannel;
@property (nonatomic,assign) NSString *sessionPreset;

在实施文件中:

    @interface AVCamCaptureManager ()

@property (nonatomic,retain) AVCaptureSession *session;
@property (nonatomic,retain) AVCaptureDeviceInput *videoInput;
@property (nonatomic,retain) AVCaptureDeviceInput *audioInput;

@end

    @implementation AVCamCaptureManager

@synthesize session = _session;
@synthesize orientation = _orientation;
@dynamic audioChannel;
@dynamic sessionPreset;

@dynamic focusMode;


- (id) init
{

3 个答案:

答案 0 :(得分:3)

@property (nonatomic,readonly,retain) AVCaptureSession *session;

这是一个外部readonly的属性。在内部,它将有一个保留新值的setter。

@property (nonatomic,assign) AVCaptureVideoOrientation orientation;

这是一个属性,它执行一个简单的赋值来存储新值(因为你不能-copy-retain原语。)

@property (nonatomic,readonly,retain) AVCaptureAudioChannel *audioChannel;

这是一个外部readonly的属性。在内部,它将有一个保留新值的setter。

@property (nonatomic,assign) NSString *sessionPreset;

这是一个执行简单赋值以存储新字符串值的属性。这通常不是一个好主意,除非您只允许预设的预定义常量。在处理NSString属性时,您通常希望它们为copy,除非您有充分的理由反对它。

在实施文件中:

@property (nonatomic,retain) AVCaptureSession *session;
@property (nonatomic,retain) AVCaptureDeviceInput *videoInput;
@property (nonatomic,retain) AVCaptureDeviceInput *audioInput;

这些与标题中声明的属性一起使用,除了现在它是readwrite。通过将标头中的版本声明为readonly,使用该类的任何人都无法访问setSession:方法。我们在内部重新声明此属性,以便我们可以访问setter(并且setter保留新值)。此外,如果标题中不存在该属性,则用户将不知道它存在,但我们仍然可以在内部使用它。

@synthesize session = _session;
@synthesize orientation = _orientation;

这意味着您希望编译器为sessionorientation属性生成适当的setter和getter,并且您希望这些属性将其值存储在_session和{ {1}}实例变量。

_orientation

这意味着将在运行时提供setter和getter的实现。除了Core Data框架提供的属性之外,您通常不会自己使用@dynamic audioChannel; @dynamic sessionPreset; @dynamic focusMode; 属性。

答案 1 :(得分:1)

在此代码中,会话属性在类之外定义为readonly,并在类内部进行读写。通过在合成它之前覆盖未命名类别中的会话属性,也将合成一个set访问器,但是头文件说它是只读的,所以其他类不知道set访问器。该类别还定义了两个根本不可见的新属性。

retain和assign关键字告诉编译器访问器方法应该如何工作。保留意味着set访问器应该保留属性的值,而assign关键字告诉它设置属性而不保留它。还有copy,它复制值,通常用于确保未设置可变值。默认值为assign,但如果没有为对象属性指定任何内容,编译器将发出警告。

答案 2 :(得分:0)

你能解释一下你对这里的困惑吗?我唯一的猜测是你对audioChannel和sessionPreset感到困惑,因为它们没有ivars并被声明为@dynamic(也有focusMode,但我甚至没有在代码中看到@property声明粘贴)。

无论如何,我希望如果您阅读其余代码,您会发现已经编写了-audioChannel-sessionPreset的getter,以及{的setter {1}}。假设是这种情况,则-setSessionPreset:声明完全没必要。 @dynamic只需告诉编译器该方法将在运行时存在;如果它们在编译时存在,那么你不需要任何指令。