当前位置: 首页 > news >正文

@property @synthesize @dynamic 及相关属性作用探究

@property :

iOS6 引入关键词. 

@property name; 指示编译器自动生成 name 的 setter 和 getter 方法 :

- (NSString *)name;

- (NSString *)name {

  return _name;

}

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

- (void)setName:(NSString *)string {

  if (_name != string) {

    [_name release];

    _name = [string retain];

  }

}

而 @synthesize name = _name; 则是先去访问同名变量 _name, 没有则定义变量 _name, 意味着先生成变量, 再生成变量的 setter 及 getter; 如果自己实现了 setter 及 getter 则系统不再实现;

如果使用的是 @synthesize name; 则系统会生成变量 name 而不会生成 _name, getter 及 setter 中所返回也会变为 name.

如果该 property 使用 getter/setter 关键字修饰的则会生成对应方法名, 返回值为 @synthesize 后变量名;

如果同时使用 getter 和 setter 关键字 且同时手动实现了 setter 和 getter,  则系统不会自动生成变量 _name, 必须使用@synthesize name = xxx 才会生成对应变量;

注 : 默认实现 @synthesize name = _name,  _name 可以是任何你想要的变量名.

另 : 对于属性和变量的理解, 属性仅仅只表示 setter 和 getter, @property 修饰的属性仅仅只是 setter 和 getter 缩写, 方便使用 'self.' 调用;  _name 才是真正的变量, 是由系统 @synthesize 生成.

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, copy) NSString * name;

@end

@implementation ViewController

@synthesize name = userName;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.name = @"1111";
    NSString * nameString = self.name;
    NSLog(@"nameString : %@ userName : %@", nameString, userName); // nameString : 1111 userName : 1111

    userName = @"2222";
    NSLog(@"self.name : %@", self.name);  // self.name : 2222
   //    NSLog(@"%@", _name); // 因为使用 @synthesize name = userName;所以报错 Use of undeclared identifier '_name'
}
@end

 

@property 参数:

读写 :

readwrite (读写) / readonly (只读),

内存管理 :

assign : 默认类型, 对 setter 方法参数不进行 retain 操作, 适用于基本数据类型.

retain : 对 setter 变量旧值进行一次 release 操作, 对参数进行 retain 操作, 适用于对象.

copy : 暂且定义为作用同 retain (具体待深浅拷贝探究).

strong : 同 retain, ARC 下使用.

weak : 作用同 assign, ARC 下使用, 不同的是可以对对象使用, 对象释放时会将对象置位 nil.

并发性 :

nonatomic / atomic 区别 : 用来决定编译器在生成的 setter 和 getter 是否为原子操作. atomic 提供线程安全, 描述该变量是否支持多线程同步访问, 系统会自动创建 lock 锁锁定变量, 而 nonatomic 禁止多线程访问, 保护变量, 提高性能.

属性默认为 atomic, 为了避免多线程访问该变量, 造成读写的不同步, 编译器会自动生成一些互斥加锁代码, 会损耗性能.

nonatomic : 如果属性无需考虑多线程的情况, 则可以使用该属性, 禁止多线程访问, 提高性能.

atomic : 系统自动生成 setter/getter, 手动生成 setter 和 getter 会警报不能配对.

#import "ViewController.h"

@interface ViewController ()

@property (atomic, copy) NSString * name;

@end

@implementation ViewController

- (void)viewDidLoad {
    __weak typeof(self) weakself = self;
    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        self.name = @"1111";
    });
    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        self.name = @"2222";
    });
    // 两秒后打印值
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"%@", weakself.name);
    });
}

- (void)setName:(NSString *)name { // Writable atomic property 'name' cannot pair a synthesized getter with a user defined setter
    _name = name;
}

@end

nonatomic : 两个线程访问 setter, 两个线程访问 getter, 如下: 两次打印结果不定, 可能是 (@"222", @"222") 也可能是 (@"11111", @"11111"), 还可能是 (@"2222", @"11111").  

所以说 nonatomic 在多线程情况下会出现问题, 如果是多线程还需进一步处理. ☆☆☆☆☆ -- 怎么处理, 使用 atomic ???

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, copy) NSString * name;

@end

@implementation ViewController

- (void)viewDidLoad {
    __weak typeof(self) weakself = self;

    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        weakself.name = @"2222";
    });
    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        NSLog(@"%@", weakself.name);
    });
    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        weakself.name = @"11111";
    });
    dispatch_async(dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT), ^{
        NSLog(@"%@", weakself.name);
    });
}

- (void)setName:(NSString *)name {
    _name = name;
}

@end

 

atomic 示例 : 

{lock}
    if (property != newValue) { 
        [property release]; 
        property = [newValue retain]; 
    }
{unlock}        

用atomic会在多线程的设值取值时加锁,中间的执行层是处于被保护的一种状态,atomic是oc使用的一种线程保护技术,基本上来讲,就是防止在写入未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

引用参考 : http://www.cnblogs.com/Rong-Shengcom/ 

补充

@dynamic: 同样是 @property 对应的关键字, 该关键字需要手动编写, 它会告诉编译器, @property 修饰的属性所对应的 getter 和 setter 是动态绑定, 由用户自己实现, 不需要自动实现, 若该属性是由 readonly 修饰, 则只需要实现一个 getter 即可. 注: 如果属性声明为 dynamic, 且用户没有实现该属性对应的 getter 和 setter, 编译时没有问题, 在用户调用属性的 getter 或 setter 的时候, 就会崩溃,报错 'unrecognized selector sent to instance', 编译时由于是@dynamic, 所以编译器不会报错, 运行时执行对应方法, 即动态绑定.

 

转载于:https://www.cnblogs.com/Stream-W/p/9606595.html

相关文章:

  • 获取网贷之家数据
  • ES6 新特性之 let, const : JavaScript在变量方面的改进。
  • sqlmap tamter
  • ubuntu apache 配置虚拟主机 与 二级域名
  • ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】...
  • java项目学习
  • 方向导数的计算与梯度
  • 大数据框架hadoop服务角色介绍
  • 谈谈Java程序员未来的出路
  • spring boot框架学习1-认识spring boot和快速入门
  • DbForge Data Compare for SQL Server入门教程:连接、同步数据库
  • mysql修改表的存储引擎(myisam=innodb)【转】
  • spring boot系列(七)spring boot 使用mongodb
  • [WCF安全系列]谈谈WCF的客户端认证[用户名/密码认证]
  • 别说国产虚拟化不行,现在国内虚拟化的主流趋势是国产化
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • iOS 颜色设置看我就够了
  • Node + FFmpeg 实现Canvas动画导出视频
  • Otto开发初探——微服务依赖管理新利器
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 经典排序算法及其 Java 实现
  • 聚类分析——Kmeans
  • 聊聊redis的数据结构的应用
  • 免费小说阅读小程序
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​用户画像从0到100的构建思路
  • # Apache SeaTunnel 究竟是什么?
  • ###STL(标准模板库)
  • #Lua:Lua调用C++生成的DLL库
  • (4)STL算法之比较
  • (4.10~4.16)
  • (第27天)Oracle 数据泵转换分区表
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (剑指Offer)面试题34:丑数
  • (四)JPA - JQPL 实现增删改查
  • (四)鸿鹄云架构一服务注册中心
  • .gitignore
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .Net Core与存储过程(一)
  • .net framework4与其client profile版本的区别
  • .NET NPOI导出Excel详解
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 指南:抽象化实现的基类
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .NET性能优化(文摘)
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • //解决validator验证插件多个name相同只验证第一的问题
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序