Designated Initializer

不稳定的传送门

合成属性

Properties don’t always have to be backed by their own instance variables.

As an example, the XYZPerson class might define a read-only property for a person’s full name:

@property (readonly) NSString *fullName;

Rather than having to update the fullName property every time the first or last name changed, it would be easier just to write a custom accessor method to build the full name string on request:

- (NSString *)fullName
{return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

  假如一个属性是另外2个属性的复合体,那么可以重写该属性的getter方法,在方法中返回2个属性的结合,就不用每次更新2个属性的时候去更新这个复合属性啦

Lazy Factory

(1)Using a factory method to get instances of a class (factory method pattern)【还不是很了解,Todo:继续查找资料】

(2)Store the instances in a map, so you get the same instance the next time you ask for an instance with same parameter (multiton pattern)【项目里搜索模块将多个viewController存在一个dictionary里,当从dictionary读不到的时候就创建一个并写入】

(3)Using lazy initialization to instantiate the object the first time it is requested (lazy initialization pattern)【按需创建】

关于Strong属性

Strong Reference Cycles

Memory for Objective-C objects is allocated dynamically (on the heap), which means you need to use pointers to keep track of an object’s address.

In Objective-C, an object is kept alive as long as it has at least one strong reference to it from another object.

  如图,如果XYZPerson没有被释放,则firstName和lastName也永远不会被释放。

  

  UITableView.h中,对delegate和dataSource的声明方式如下  

@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;

  注意到,delegate和dataSource都是weak而不是strong,为什么呢?

  比如,现在我们创建一个具有UITableView的Controller,则该Controller中声明UITableView如下:

@property UITableView *tableView;

  注意,@property默认是strong的,回到刚刚那个问题,如果delegate是strong会发生什么事情呢?当我们为该tableView设置delegate的时候,即

tableView.delegate = self;

  此时Controller和TableView的关系如下:

  这2个Object相互之间是strong关系,就是说已经产生了Strong Reference Cycle,我们知道"An object is kept alive as long as it has at least one strong reference to it from another object.",那么这2个冤家就永远你中有我,我中有你,谁也不释放谁了。死锁!

  解决方法就是将其中一个关系改为weak,明显将delegate属性声明为weak是合理的,UITableView也是这样做的。dataSource属性同理。所以结论就是,任何delegate的属性都不应该为strong。

局部变量,默认是__strong

  为什么默认是__strong而不是__weak呢?因为方便!所有默认值的设置就是为了方便。

NSDate *originalDate = self.lastModificationDate;
self.lastModificationDate = [NSDate date];
NSLog(@"Last modification date changed from %@ to %@",
originalDate, self.lastModificationDate);NSDate *__weak originalDate = self.lastModificationDate;
self.lastModificationDate = [NSDate date];
NSLog(@"Last modification date changed from %@ to %@",
originalDate, self.lastModificationDate);

  以上2段代码的区别就是,第一段没问题,第二段,当self.lastModificationDate重新被赋值之后,它原本所指向的内存已经没有strong指针指向了,只有一个weak的originalDate指着,此时这块内存极有可能被系统释放掉。originalDate就成了悬浮指针。

  所以大部分情况下还是要使用__strong的,自然默认值为__strong也就合情合理了。

多线程中的strong与weak

In situations like this, you might want to cache the weak property in a strong variable to ensure that it is kept in memory as long as you need to use it:

- (void)someMethod
{NSObject *cachedObject = self.weakProperty;[cachedObject doSomething];...[cachedObject doSomethingElse];
}

  

  要时刻测试weak属性是否还存在啊,如下:

if (self.someWeakProperty)
{[someObject doSomethingImportantWith:self.someWeakProperty];
}

  但是这就够了吗?并不是,多线程下,应该这样

 NSObject *cachedObject = self.someWeakProperty;              // 1if (cachedObject) {                                       // 2[someObject doSomethingImportantWith:cachedObject];   // 3}                                                         // 4cachedObject = nil;                                       // 5

  Todo:多线程的知识还是得补补,这里不是很懂

关于Copy属性

copy属性与NSMutableString

假如当前Controller有以下属性:

@property NSString *firstName;

在某个地方

NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.firstName = nameString;  //此时指向了NSMutableString
[nameString appendString:@"ny"];

self.firstName的值为"Johnny",一个应为NSString*的值却莫名其妙被修改了?因为它指向了一个它不该指向的地方。

解决方案如下,为firstName添加copy属性

@property (copy) NSString *firstName;

在某个地方

NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.firstName = nameString;  //此时self.firstName指向的是nameString的copy版本,该版本是NSSting类型,且对这个版本的String对象持strong指针
[nameString appendString:@"ny"];

self.firstName的值为"John",它与nameString指向的是两个完全不同的地方。

将传入的参数copy一份复制给成员变量

- (id)initWithSomeOriginalString:(NSString *)aString {self = [super init];if (self) {_instanceVariableForCopyProperty = [aString copy];}return self;
}

假如不想让成员变量与传入的参数共同指向一个地方,那么只要copy一份就可以啦

Any object that you wish to set for a copy property must support NSCopying

Nothing

转载于:https://www.cnblogs.com/chenyg32/p/4856246.html

《Programming with Objective-C》第四章 Encapsulating Data相关推荐

  1. 《Credit Risk Scorecard》第四章:Data Review and Project Parameters

    第四章:Scorecard Development Process, Stage 2: Data Review and Project Parameters 一: data avaliablity a ...

  2. GXT之旅:第四章:Data与Components(4)——远程数据(remote data)

    使用remote data stores的数据来源不单单可以从client-side获得(就是从Registry里获得),也可以通过调用远程数据来获得.对于远程数据的加载和处理工作,GXT已经提供了轻 ...

  3. 【读书笔记】.NET本质论第四章-Programming with Type(Part Two)

    欢迎阅读本系列其他文章: [读书笔记].NET本质论第一章 The CLR as a Better COM [读书笔记].NET本质论第二章-Components(Part One) [读书笔记].N ...

  4. 第四章:缓冲区、着色器、GLSL

    原文链接: http://www.rastertek.com/gl40tut04.html Tutorial 4: Buffers, Shaders, and GLSL 第四章:缓冲区.着色器.GLS ...

  5. 《Programming WPF》翻译 第7章 3.笔刷和钢笔

    原文:<Programming WPF>翻译 第7章 3.笔刷和钢笔 为了在屏幕上绘制一个图形,WPF需要知道你想要为图形填充什么颜色以及如何绘制它的边框.WPF提供了一些Brush类型支 ...

  6. 《Programming WPF》翻译 第8章 2.Timeline

    <Programming WPF>翻译 第8章 2.Timeline 原文:<Programming WPF>翻译 第8章 2.Timeline Timeline代表了时间的延 ...

  7. 【正点原子STM32连载】第四章 STM32初体验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  8. 【《Real-Time Rendering 3rd》 提炼总结】(十一) 第十四章 : 游戏开发中的渲染加速算法总结

    本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/78884513 导读 这是一篇1万3千 ...

  9. Frank Luna DirectX12阅读笔记:绘制进阶(第八章-第十四章)

    目录 第八章 光照 8.1 光和材质的交互 8.2 法向 8.3 光照中其他重要的向量 8.4 Lambert余弦定律 8.5 散射光(diffuse lighting) 8.6 环境光(ambien ...

最新文章

  1. Spark函数:cogroup
  2. python元组操作_Python:元组操作总结
  3. BSD配置SSH服务
  4. java蓝桥杯算法训练 相l邻字母(题解)
  5. jdk版本低于1.7 waterdrop 打不开解决
  6. FSG压缩壳和ImportREC的使用 - 脱壳篇05
  7. 金蝶盘点机金蝶条码管理方案实施金蝶仓库条码管理实现方法
  8. MathType数学公式编辑器,编辑数学资料工具
  9. 传染病研究-非靶向下一代宏基因组测序(mNGS)分析
  10. 小程序+二维码(带logo图片,可直接运行)
  11. iframe预览文件
  12. IIC驱动0.96寸OLED屏幕显示(51单片机)
  13. 信息系统分析与设计 机票预定管理系统
  14. try、catch、finally 用法总结
  15. brat报错:The server encountered a serious error, please contact the administrators at ____ and give th
  16. chrom flash提示地区不兼容, 亲测可用
  17. Android之扫描二维码和根据输入信息生成名片二维码
  18. ThreadPoolExecutor参数说明
  19. 极路由云平台倒闭,路由器免插件离线ROOT方法
  20. 有了 HTTP 协议,为什么还需要 Websocket?

热门文章

  1. Android设计模式——抽象工厂方法模式
  2. Javascript学习总结 - JS基础系列三
  3. iOS 消息推送原理及实现Demo
  4. 项目以任务还是以功能为中心?
  5. Mybatis 输入映射
  6. (68)Vue-cli 目录与文件
  7. 知道 | 同学,你都了解关系型数据库,确定不了解一下这种数据库吗?
  8. Kali Linux之软件安装、卸载、更新和修改更新源
  9. Bootstrap缩略图.thumbnail
  10. HTML pre元素