zoukankan      html  css  js  c++  java
  • 理解 Objective-c "属性"

    理解 Objective-c "属性"

    @property 是OC中能够快速定义一个属性的关键字,如下我们定义一个属性。

    @property	NSString		*String;
    

    这样我们就可以使用这个属性

    属性的实质

    • 在属性被加入OC以前我们每次声明一个实例变量都要自己声明并实现存取方法
    //
    // Created by chao on 15/8/29.
    // Copyright (c) 2015 ___FULLUSERNAME___. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @interface Person : NSObject{
        NSString *firstName;
        NSString *lastName;
    }
    
    - (void)setFirstName:(NSString *)first;
    - (NSString *)firstName;
    - (void)setLastName:(NSString *)last;
    - (NSString *)lastName;
    @end
    //在.m文件里实现
    
    #import "Person.h"
    @implementation Person {
    }
    
    - (void)setFirstName:(NSString *)first {
        firstName = [first copy];
    }
    
    - (NSString *)firstName {
        return  firstName;
    }
    
    - (void)setLastName:(NSString *)last {
        lastName = [last copy];
    }
    
    - (NSString *)lastName {
        return lastName;
    }
    
    @end
    

    现在有了@property只要简单的声明一下就可以让编译器替我们做以上哪些繁杂的工作。

    @property	NSStrinng	*firstNmae;
    @property	NSString	*lastName;
    
    • 声明属性 编译器除了生成存取方法代码外,还要自动向类中添加适当类型的实例变量。

    编译器会自动在属性名之前添加下划线,一次作为实例变量的名字,在上面的声明中会生成两个实例变量
    _firstNam, _lastName.我们也可以使用@synthesize语法指定实例变量的名字。

    @synthesize firstName   =   _myFirstName; //使用指定的实例变量名称
    @synthesize	lastName = _myLastName;//如果没有特殊需要尽量使用系统默认的名称
    
    • 如果不想令编译器合成存取方法, 则可以自己实现,如果只实现了其中一个存取方法, 则另外一个还是会由编译器重新合成,你可以使用@dynamic 关键字阻止编译器自动合成存取方法。

    @dynamic关键字

    @property	NSStrinng	*firstNmae;
    @property	NSStrinng	*firstNmae;
    
    @dynamic	firstName, lastname;	//编译器不会自动为这两个属性合成存取方法,或实例变量。
    

    属性的特性

    存取类型

    • readwrite (默认)编译器自动创建存方法和取方法
    • readonly 不生成存方法,如果一个属性不允许修改则可以将其声明为存方法。

    在为以上类添加一个只读的ID和weight属性。

    @property   (readonly)  NSInteger   ID;
    @property   (readwrite) NSInteger   height;
    

    如果我们这程序中试图修改person 的ID属性编译器就会报错

    readonly error

    生命周期类型(内存管理类型)

    生命周期类型的特性包括, assign, strong, weak和copy 这些特性决定了存方法如何处理与其相关的内存管理问题

    • assign (默认)最简单的,存入的值会将传入的值直接赋给实例变量。
    @property	(assign)	NSInteger	ID;
    这段代码等同于实现了一下存方法
    - (void)setID:(NSInteger)d {
    	ID = d;
     }
    
    • strong 特性要求保留传入的对象,并放弃原有对象(如果原有对象不在有其他拥有方,就会被释放)。凡是指向对象的实例变量,通常都应该使用strong
    • weak 要求不保留传入的对象,相应的存取方法会将传入的对象直接赋给实例变量。如果该对象被释放,那么相应的实例变量会呗自动置nil
    • copy 特性要求拷贝传入对象,并将新对象赋给实例变量。

    copy 详解

    看了很多博客讲解的copy都只是简单的说了一下,copy特性要求拷贝传入对象。并没有进行深入的讲解,比如为什么要copy传入对象,下面我写一下我自己对copy的理解

    1. 在OC中有些类会有特定的可修改的子类,比如 像NSString 和 NSMutableString 这些类我们平常使用时一般都声明为copy。像下面我们定义一个NSString 属性,但是给其存方法传入 NSMutableString 是合法的,声明为 copy,就可以避免修改 原对象对实例变量的影响
    @property 	(strong)	NSString		*firstName;
    @property	(copy)	NSString		*lastName;
    NSMutableString	 *name = [[NSMutable alloc] initWithString:@"Li"];
    [person 	setFirstNmae:name];
    [person setLastName:name];//这样修改name 不会对实例变量产生影响。
    //看以下程序的输出
     NSMutableString  *firstName = [NSMutableString stringWithString:@"Zhang"];
     NSMutableString  *lastName  = [NSMutableString stringWithString:@"San"];
    person.firstName = firstName;
    person.lastName = lastName;
    NSLog(@"修改前的 :%@%@", person.firstName, person.lastName);
    [firstName appendString:@"fe"];
    [lastName appendString:@"aefa"];
    NSLog(@"修改后的 :%@%@", person.firstName, person.lastName);
    NSLog(@"%@%@", firstName, lastName);
    

    copy mark

    2.如果传入的对象是不可修改的,copy方法实际是在调用copyWithZone:一般我们自定义的对象如果要求copy,应该重写 copyWithZone:方法从而优化copy过程

    - (id)copyWithZond {
    	return self;
    }
    
    1. copy返回的值总是不可修改的,如果需要copy出可修改的对象,需要使用对应的mutableCopy方法

    atomic 和nonatomic

    • 如果不声明默认是atomic,atomic属性的存方法并不会对多线程下的安全有太大帮助,所以一般用nonatomic,而且atomic会影响性能。(确保线程安全必定会有额外开销)
  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/code-changeworld/p/4782705.html
Copyright © 2011-2022 走看看