zoukankan      html  css  js  c++  java
  • 属性(,KVC,nonatomic,atomic,assign,retain,synthesize,readwrite,readonly)

    属性(Property)

     

      封装一个学生类, 

            实例变量: name, age 

            自定义初始化方法 

            便利构造器 

            setter, getter 

            重写description方法

    Student.h
    #import <Foundation/Foundation.h>
    @interface Student : NSObject {
        NSString *_name;
        NSInteger _age;
        NSString *_gender;
    }
    //属性的声明
    @property NSString *gender;
    - (void)setName:(NSString *)name;
    - (NSString *)name;
    - (void)setAge:(NSInteger)age;
    - (NSInteger)age;
    - (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
    + (instancetype)studentWithName:(NSString *)name age:(NSInteger)age;
    - (void)show;
    @end
    Student.m
    #import "Student.h"
    
    @implementation Student
    //属性的实现
    @synthesize gender;
    - (void)setName:(NSString *)name {
        _name = name;
    }
    - (NSString *)name {
        return _name;
    }
    - (void)setAge:(NSInteger)age {
        _age = age;
    }
    - (NSInteger)age {
        return _age;
    }
    - (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
        self = [super self];
        if (self) {
            _name = name;
            _age = age;
        }
        return self;
    }
    + (instancetype)studentWithName:(NSString *)name age:(NSInteger)age {
    //    Student *stu = [[Student alloc] init];
    //    [stu setName:name];
    //    [stu setAge:age];
        return [[Student alloc] initWithName:name age:age];
    }
    - (void)show {
        NSLog(@"name:%@, age:%ld", _name, _age);
    
    }
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"name:%@, age:%ld", _name, _age];
    }
    @end
        main.m    
           Student *student = [[Student alloc] initWithName:@"小花" age:18];
            NSLog(@"%@", student);
            //使用自定义的类生成的对象, 打印结果<类名: 地址>
            
            //打印对象的实例变量
            NSLog(@"name:%@, age:%ld", [student name], [student age]);
            
            //封装方法, 快速打印实例变量
            [student show];

            %@打印的实质: 打印度是这个对象调用description方法返回的字符串

            descriptionNSObject中的方法

            NSLog(@"%@", student);
            NSLog(@"%@", [student description]);
    点语法
            Student *stu = [[Student alloc] init];
            NSLog(@"%@", stu);
            
    通过setter为变量赋值
            [stu setName:@"李思思"];
            [stu setAge:28];
            
    通过getter取实例变量的值
            NSLog(@"%@, %ld", [stu name], [stu age]);

            点语法的作用: 快速调用settergetter

            点语法的前提: 必须要有settergetter

            : 点语法出现在=号的左侧, 调用setter, 其他位置调用getter

            stu.name = @"小哇";
            stu.age = 28;
            NSLog(@"%@, %ld", stu.name, stu.age);

            属性: 快速生成settergetter方法

            属性声明

            格式: @property数据类型实例变量名;

            属性实现

            格式:

            @synthesize实例变量名;

            stu.gender = @"";
            NSLog(@"%@", stu.gender);

            定义一个手机类

            实例变量: 品牌, 价格, 颜色

            属性

            重写description

    Phone.h
    #import <Foundation/Foundation.h>
    @interface Phone : NSObject {
    //    NSString *_brand;
    //    CGFloat _price;
    //    NSString *_color;
    }
    @property NSString *brand, *color;
    @property CGFloat price;
    @end
    Phone.m
    #import "Phone.h"
    @implementation Phone
    //@synthesize brand, price, color;
    //如果不写属性的实现, 默认系统补上的形式
    //@synthesize  brand = _brand, price = _price, color = _color;
    //@synthesize  brand;
    //1.自动生成一个实例变量brand;
    //2.setter方法和getter方法对实例变量brand进行操作
    //@synthesize  brand = _brand;
    //1.自动生成一个实例变量_brand;
    //2.setter方法和getter方法对实例变量_brand进行操作
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"brand:%@ price:%.2f color:%@", _brand, _price, _color];
    }
    @end
    main.m
            Phone *phone = [[Phone alloc] init];
            phone.brand = @"iPhone 6s";
            phone.price = 1998;
            phone.color = @"土豪金";
            NSLog(@"%@", phone);

     属性的优化

            1.属性声明的优化, 如果数据类型相同, 可以写在一行, 用逗号隔开

            : 对象要加*

            2,属性实现的优化: 多个属性实现可以写在一行, 用逗号隔开

            3.属性的实现部分是可以省略的, 系统自动补上属性的实现部分

            4.实例变量可以省略, 属性会自动补上实例变量

     封装一个猫类

            实例: 姓名, 品种, 年龄, 颜色

    Cat.h
    #import <Foundation/Foundation.h>
    @interface Cat : NSObject
    @property (nonatomic, retain) NSString *name, *type, *color;
    @property (nonatomic)NSInteger age;
    //苹果的习惯: 如果属性是BOOL类型, 一般会修改getter方法的名字, 改成"is+实例变量"
    @property (nonatomic, getter=isSame) BOOL same;
    @end
    Cat.m
    #import "Cat.h"
    @implementation Cat
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"name:%@ type:%@ age:%ld color:%@", _name, _type, _age, _color];
    }
    @end

      属性的修饰词

            作用: 管理和控制settergetter

      1.多线程组

            a. atomic: 原子性, 同一时刻只能执行一种操作(gettersetter), 安全性高, 执行效率比较低, 一般用于多线程, 默认值

            b. nonatomic: 非原子性的, 同一时刻能执行多种操作(gettersetter), 执行效率高

            : 一般优先写nonatomic, 多线程下为了安全起见, 才写atomic

    2.内存管理组

            a. assign: 基本数据类型(int, char, float, double, long, short, BOOL, NSInteger, CGFloat), 默认值

            b. retain: 对象

            c. copy: 对象, 必须遵守<NSCopying>协议

    3.读写组

            a. readwrite: 读写, 会生成settergetter, 默认值

            b. readonly: 只读, 只生成getter

    4.方法重命名组

            a. setter=名字

            b. getter=名字

    KVC: key-value coding, 键值编码, 提供了一种间接访问属性的方式

    Game.h
    #import <Foundation/Foundation.h>
    @interface Game : NSObject
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic) CGFloat time;
    @property (nonatomic) NSInteger count;
    @end
    Game.m
    #import "Game.h"
    @implementation Game
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"name:%@ time:%.2f count:%ld", _name, _time, _count];
    }
    @end
    main.m
            //setter
            [game setName:@"双升"];
            NSLog(@"%@", [game name]);
            //点语法
            game.name = @"斗地主";
            NSLog(@"%@", game.name);
            
            //间接访问(KVC)
            [game setValue:@"接竹竿" forKey:@"name"];
            NSLog(@"%@", [game valueForKey:@"name"]);
            //注: key内填写属性名

     KVC检索的过程

            1.getter,  setter

            2.实例变量_<key>, <key>

            3.setValue:forUndefinedKey:, valueForUndefinedKey

    Boy.h
    #import <Foundation/Foundation.h>
    //在外部访问实例变量, 有哪些途径
    //1. @public, 通过->访问
    //2. setter, getter
    //3. KVC
    @interface Boy : NSObject {
        NSString *_name;
        NSInteger _number;
    }
    @end
    Boy.m
    #import "Boy.h"
    @implementation Boy
    - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
        NSLog(@"value:%@ key:%@", value, key);
        
    }
    - (id)valueForUndefinedKey:(NSString *)key {
        return nil;
    }
    @end
    main.m
            Boy *boy = [[Boy alloc] init];
            [boy setValue:@"李磊" forKey:@"name"];
            NSLog(@"%@", [boy valueForKey:@"name"]);     
            [boy setValue:@"18" forKey:@"age"];
            NSLog(@"%@", [boy valueForKey:@"age"]);    
            [boy setValue:@15 forKey:@"number"];
            NSLog(@"%@", [boy valueForKey:@"number"]); 
            Boy *boy1 = [[Boy alloc] init];
            [boy1 setValuesForKeysWithDictionary:@{@"name": @"韩梅梅", @"number": @19}];
            NSLog(@"%@ %@", [boy1 valueForKey:@"name"], [boy1 valueForKey:@"number"]);

    属性中出现的问题

    Girl.h
    #import <Foundation/Foundation.h>
    @interface Girl : NSObject
    @property (nonatomic) NSInteger age;
    @end
    Girl.m
    #import "Girl.h"
    @implementation Girl
    //当同时重写了setter和getter方法后, @synthesize age = _age;就失效了
    //解决方案: 自己补上@synthesize age = _age;
    @synthesize age = _age;
    //当属性生成的setter方法不满足需求时, 可以重写setter方法
    - (void)setAge:(NSInteger)age {
        if (age > _age) {
            _age = age;
        }
    }
    //当属性生成的getter方法不满足需求时, 可以重写setter方法
    - (NSInteger)age {
        return  _age - 2;
    }
    @end
    main.m
            Girl *girl = [[Girl alloc] init];
            girl.age = 17;
            NSLog(@"%ld", girl.age);
            //每次赋值的年龄都大于上一次
            girl.age = 10;
            NSLog(@"%ld", girl.age);

     

     

     

     

    The one who wants to wear a crown must bear the weight!
  • 相关阅读:
    面试官问你如何解决web高并发这样回答就好了
    react-native页面间传递数据的几种方式
    图片上传知识点梳理
    使用Vue CLI 3将基于element-ui二次封装的组件发布到npm
    OpenCV学习笔记09--通过cvPtr2D或指针算法绘制图形
    [code segments] OpenCV3.0 SVM with C++ interface
    LINUX设备驱动程序笔记(一)设备驱动程序简单介绍
    redis 简单安装使用
    Linux常见压缩命令
    计算机网络13--网络应用的体系结构
  • 原文地址:https://www.cnblogs.com/OrangesChen/p/4866110.html
Copyright © 2011-2022 走看看