zoukankan      html  css  js  c++  java
  • iOS学习笔记---oc语言第八天

    属性

    能在一定程度上简化代码,并且增强实例变量的访问安全性

    属性的声明:使用@property声明属性  eg:@property NSSstring *name;相当于@interface中声明了两个方法

    - (void)setName:(NSString *)name;

    - (NSString *)name;

    属性的实现:使用@synthesize实现属性 ,eg:@synthesize name = _name;

    相当于@implementation 实现了

    - (void)setName:(NSString *)name;

    - (NSString *)name;

    //Person.h
    @interface Person : NSObject
    {
        NSString *_name;   //姓名
        NSInteger _age;    //年龄
        CGFloat _score;
        NSString *_sex;
    }
    @property CGFloat score;
    //可以把相同类型的属性放在同一行进行声明,但是通常分开写
    @property NSString *name,*sex;
    //等价于下面两行
    //- (void)setName:(NSString *)name;//设置名字
    //- (NSString *)name;//获得名字
    
    @property NSInteger age;
    //等价于下面两行
    //- (void)setAge:(NSInteger)age;//设置年龄
    //- (NSInteger)age;//获得年龄
    @end
    //Person.m
    #import "Person.h"
    
    @implementation Person
    //=号前面是你声明的属性
    //=号后面填写setter为哪个实例变量赋值,getter获取哪个实例变量的值
    @synthesize name = _name,sex = _sex,age = _age,score =_score;//可以写成一行,一般写成两行,一行可读性差
    //@synthesize age = _age;//实现age属性
    //@synthesize score = _score;//实现score属性
    //- (void)setName:(NSString *)name//设置名字
    //{
    //    _name = name;
    //}
    //- (NSString *)name//获得名字
    //{
    //    return  _name;
    //}
    //- (void)setAge:(NSInteger)age//设置年龄
    //{
    //    _age = age;
    //}
    //- (NSInteger)age//获得年龄
    //{
    //    return _age;
    //}
    @end

     属性的属性

    第一类:读写性控制(readonly、readwrite、setter、getter)

    如果读写性控制的关键字是readonly,是告诉编译器,只声明getter⽅方法(无setter⽅方法)。
    例如:@property(readonly)NSString *name;

    //等价于 - (NSString *)name;

    如果是readwrite,告诉编译器,既声明setter⼜又声明getter。
    例如: @property(readwrite)NSString *name;

    //等价于 - (NSString *)name;

    - (void)setName:(NSString *)name; readwrite是读写性控制的默认设置。

    第⼆类:原子性控制(nonatomic、atomic)

    如果原子性控制的关键字是atomic。setter、getter⽅法在多线程访 问下是绝对安全的,即setter、getter内部做了多线程访问处理。原⼦ 性控制的默认设置是atomic

    如果原子性控制的关键字是nonatomic。setter、getter⽅法内部不会 做多线程访问处理,仅是普通的setter、getter方法

    程序开发过程中,setter、getter处都在用,如果使用atomic,

    需要不断的对setter、getter加锁解锁以保证线程访问安全,会很占 ⽤系统资源,降低系统性能。

    通常设置为nonatomic,某些属性需要线程安全的时候,才定义为 atomic。

    例如:@property (readwrite,nonatomic)NSString *name;
    //等价于 – (NSString *)name;

    - (void)setName:(NSString *)name;

    第三类:语义设置(assign、retain、copy)

    如果语义设置的关键字是assign。setter、getter内部实现是直接赋值。

    例如:@property(nonatomic,assign)NSString *name;
    - (void)setName:(NSString *)name{
        

        _name = name;
    }

    - (NSString *)name{
        return _name;
        

    }

    //assign修饰下,setter是直接为实例变量赋值

    //assign修饰下,getter是直接获取实例变量

    在如果语义设置的关键字是retain。setter、getter的内部实现会做内存优化。

    //retain关键字下,setter 是企业必考的笔试题

    例如:@property(nonatomic,retain)NSString *name;

    - (void)setName:(NSString *)name{
        if(_name != name){
            

            [_name release];
            

            _name = [name retain];
        }
        

    }

    }

    - (NSString *)name{
        

        return [[_name retain]autorelease];

    }

    如果语义设置的关键字是copy。setter、getter的内部实现也会做内存优化。

    例如:@property(nonatomic,copy)NSString *name;

    - (void)setName:(NSString *)name{
        if(_name != name){
            

            [_name release];
            

            _name = [name copy];
        }
        

    }

    }

    - (NSString *)name{
        

        return [[_name retain]autorelease];

    }

    如果属性是⾮对象类型(⽐比如int,float等)属性的语义设置使用assign。

    如果属性是对象类型(⽐如NSStrng、NSArray等)属性的语义设置使用retain。

    如果属性是对象类型并且想得到参数的copy,使⽤用copy关键字。

    -(instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age
    {
        self = [super init];
        if (self) {
            //给实例变量赋值,使用setter ,不再单独赋值,因为setter内部做了内存优化
            [self setName:name];
            [self setAge:age];
            [self setSex:sex];
            
           
        }
        return self;
    }
    //初始化以后就这样写

    点语法

    凡是符合系统默认setter、getter书写格式的⽅法都可以使⽤用点语 法。

    例如:[person1 setName:@”zhangsan”];可以等价写成 person1.name = @”zhangsan”;。

    NSString *name = [person1 name];可以等价写成
    NSString *name = person1.name;

    属性是⼀对getter、setter⽅法,点语法是属性的另一种调用格式

    kvc

    KVC(Key-Value-Coding),键值编码,是⼀种间接访问实例变量的方法.

    key:键,⽤于标识实例变量

    vlaue:实例变量对应的值

    修改值

    setValue:forKey:

    setValue:forKeyPath:

    setValue:forUndefinedKey:

    setValuesForKeysWithDictionary:

    获取值

    valueForKey:

    valueForKeyPath:

    valueFoeUndefineKey:

    注意事项

    当key不存在的时候,会执⾏setValue:forUndefinedKey:

    系统默认实现是抛出一个异常

    一个kvc例子,一个Person类,一个A类

    //A.h中代码
    #import <Foundation/Foundation.h>
    
    @interface A : NSObject
    {
        NSString *_name;
    }
    
    - (void)printName;
    @end
    //A.m中代码
    #import "A.h"
    
    @implementation A
    -(void)printName
    {
        NSLog(@"%@ ",_name);
    }
    @end
    //Person.h中代码
    #import <Foundation/Foundation.h>
    #import "A.h"
    @interface Person : NSObject
    
    {
        NSString *_name;
    //    NSString *_sex;
        NSInteger _age;
        A *_a;
    }
    - (void)sayHi;
    - (id)init;
    @end
    //Person.m中代码
    #import "Person.h"
    @implementation Person
    -(void)sayHi
    {
        NSLog(@"hello,this is %@ %ld years old   ",_name,_age);
        [_a printName];
    }
    //重写方法   当key不存在的时候会调用这个方法,系统的默认实现是抛出一个异常,我们可以重写这个方法.解决key不存在产生崩溃的问题
    - (void)setValue:(id)value forUndefinedKey:(NSString *)key
    {
    
    }
    //当key为非对象类型,且value设置为nil的时候.会调用这个方法,系统默认实现是抛出一个异常,我们可以重写这个方法,解决value为nil的问题
    - (void)setNilValueForKey:(NSString *)key
    {
    
    }
    -(id)init
    {
        self = [super init];
        if (self) {
            _a = [[A alloc] init];
        }
        return self;
    }
    @end
    //main.m中代码
    #import <Foundation/Foundation.h>
    #import "Person.h"
    int main(int argc, const char * argv[])
    {
    
        Person *p1 = [[Person alloc] init];
        [p1 setValue:@"张三" forKey:@"name"];//kvc赋值
        [p1 setValue:@18 forKey:@"age"];
        [p1 sayHi];
        [p1 setValuesForKeysWithDictionary:@{@"name": @"张三",@"age": @18,@"sex": @""}];//比较好用
        [p1 sayHi];
        [p1 setValue:@"哇哈哈" forKeyPath:@"a.name"];
        [p1 sayHi];
        return 0;
    }
  • 相关阅读:
    图书管理系统---基于form组件和modelform改造添加和编辑
    Keepalived和Heartbeat
    SCAN IP 解释
    Configure Active DataGuard and DG BROKER
    Oracle 11gR2
    我在管理工作中積累的九種最重要的領導力 (李開復)
    公募基金公司超融合基础架构与同城灾备建设实践
    Oracle 11g RAC for LINUX rhel 6.X silent install(静默安装)
    11gR2 静默安装RAC 集群和数据库软件
    Setting Up Oracle GoldenGate 12
  • 原文地址:https://www.cnblogs.com/limicheng/p/3821706.html
Copyright © 2011-2022 走看看