zoukankan      html  css  js  c++  java
  • Object-c中的属性和成员变量的关系详解

    很多人在初学移动开发的时候会对object-c中的合成存取方法感到疑惑,此处尝试为看到本文有缘人答疑解惑,鄙人才疏学浅,难免有疏漏谬误之处,热烈欢迎诸位看官拍砖指点.

    1.合成存取方法:

    OC为增加开发效率,从2.0之后不需要程序员自己来写成员变量的setter和getter方法,取而代之的是自动合成的setter和getter。

    系统自动合成setter和getter需要2步:

    1. 在类interface部分用@propert指令定义属性。
    2. 在实现部分用@synthesize指令声明属性。

    属性的定义:如果为某个类定义了一个成员变量并提供了相应地setter、getter方法,那么可称为定义了一个属性(property)。

    使用@synthesize的语法格式如下:

    @synthesize 属性名 [=成员变量名];

    如果@synthesize后没有属性,如果没有指定成员变量名,成员变量默认与合成的getter方法同名。 这里需要注意的是,此行为可能导致莫名其妙的错误,请看代码:

    //接口部分
    #import
    <Foundation/Foundation.h> @interface setGet : NSObject @property (setter=setAge:) int age; @property NSString *name; @end
    //实现部分
    #import
    "setGet.h" @implementation setGet @synthesize age,name; - (void) setAge:(int)age { NSLog(@"Call setter method!"); self.age=age; } @end
    //主程序部分
    #import
    <Foundation/Foundation.h> #import "setGet.h" int main(int argc, const char * argv[]) { @autoreleasepool { setGet* test=[[setGet alloc] init]; test.age=80; NSLog(@"The age is:%d",test.age); } return 0; }

    在以上测试代码中,将会无限输出:Call setter method!

    具体原因不言自明,正因为没有在@synthesize部分对属性名指定成员变量名,导致了程序产生了递归。

    只要在实现部分稍作改动,程序便正常输出:

    //实现部分修改
    #import "setGet.h"
    
    @implementation setGet
    @synthesize age=whatever,name;
    - (void) setAge:(int)age
    {
        NSLog(@"Call setter method!");
        self->whatever=age;
        // or :whatever=age;
        
    }
    @end

    不过OC规范一般是下划线开头来定义成员变量:_age。

    补充一句:

    “.”的用法仅限于getter和setter方法,用于左值则调用setter方法,用于右值则调用getter方法(如主程序中的NSLog中算是右值)。

  • 相关阅读:
    iPhone开发之多线程使用
    iPhone开发之启动画面及动画
    Keyboard 遮挡 UITextField
    iPhone发布之图标大小和设置
    Linux文件目录及其作用
    UIView设置背景图片
    通过点击事件轮换隐藏和显示导航栏
    内存检测
    iPhone开发之自定义柱状图
    给UIImageView添加点击事件
  • 原文地址:https://www.cnblogs.com/wangjunyan/p/4277986.html
Copyright © 2011-2022 走看看