How Not to Crash #6: Properties and Accessors(属性,存储器方法使问题)
How Not to Crash #6: Properties and Accessorshtml, body {overflow-x: initial !important;}html { font-size: 14px; }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1rem; line-height: 1.42857143; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); overflow-x: hidden; }
a:active, a:hover { outline: 0px; }
::selection { background-color: rgb(181, 214, 252); text-shadow: none; background-position: initial initial; background-repeat: initial initial; }
#write { max-width: 854px; margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: pre-wrap; text-align: justify; padding-bottom: 70px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export #write { margin: 0px auto; }
#write > p:first-child, #write > ul:first-child, #write > pre:first-child, #write > blockquote:first-child, #write > div:first-child { margin-top: 30px; }
img { max-width: 100%; }
input, button, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
::before, ::after, * { box-sizing: border-box; }
#write p, #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write div, #write pre { width: inherit; }
h1 { font-size: 2rem; }
p, .mathjax-block { display: block; -webkit-margin-before: 1rem; -webkit-margin-after: 1rem; -webkit-margin-start: 0px; -webkit-margin-end: 0px; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: bold; font-style: italic; }
a { cursor: pointer; }
li span { min-width: 10px; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; margin: 4px 0px 0px; }
tr { page-break-inside: avoid; page-break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; page-break-inside: auto; }
table.md-table td { min-width: 80px; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror-code pre { padding: 0px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
.md-fences, pre.md-fences { font-size: 0.9rem; display: block; page-break-inside: avoid; text-align: left; overflow: visible; white-space: pre; position: relative !important; }
.md-fences .CodeMirror.cm-s-default.CodeMirror-wrap { top: -1.6em; margin-bottom: -1.6em; }
.md-fences.mock-cm { white-space: pre-wrap; }
.footnotes { color: rgb(136, 136, 136); font-size: 0.9rem; padding-top: 1em; padding-bottom: 1em; }
.footnotes + .footnotes { margin-top: -1em; }
sub, sup { line-height: inherit; position: inherit; top: inherit; vertical-align: super; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background-color: transparent; text-decoration: none; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1rem; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: normal; text-align: left; box-sizing: content-box; direction: ltr; background-position: initial initial; background-repeat: initial initial; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li p, li .mathjax-block { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; }
@media print {
html, body { height: 100%; }
.typora-export * { -webkit-print-color-adjust: exact; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
#write pre.md-meta-block { font-size: 0.8rem; min-height: 2.86rem; white-space: pre; background-color: rgb(204, 204, 204); display: block; background-position: initial initial; background-repeat: initial initial; }
p > .md-image:only-child { display: inline-block; width: 100%; text-align: center; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.mathjax-block { white-space: pre; padding-bottom: 0.65rem; overflow: hidden; width: 100%; }
p + .mathjax-block { margin-top: -1.143rem; }
.mathjax-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: none; box-shadow: none; }
:focus { outline: none; box-shadow: rgb(79, 172, 249) 0px 0px 2px 3px, rgb(120, 174, 218) 0px 0px 2px inset; }
.task-list { list-style-type: none; }
.task-list-item { position: relative; padding-left: 1em; }
.task-list-item input { position: absolute; top: 0px; left: 0px; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc::after, .md-toc-content::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: bold; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
.md-toc-h6 { margin-left: 12em; }
@media screen and (max-width: 48em) {
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 { margin-left: 9.5em; }
}
a.md-toc-inner { color: inherit; font-size: inherit; font-style: inherit; font-weight: inherit; text-decoration: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: '.'; }
.md-tag { opacity: 0.5; }
h1 .md-tag, h2 .md-tag, h3 .md-tag, h4 .md-tag, h5 .md-tag, h6 .md-tag { font-weight: initial; opacity: 0.35; }
html { font-size: 16px; }
html, body { background-color: rgb(243, 242, 238); font-family: 'PT Serif'; color: rgb(31, 9, 9); line-height: 1.5em; }
#write { max-width: 36em; }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote::before, blockquote::after, q::before, q::after { content: none; }
table { border-collapse: collapse; border-spacing: 0px; }
h1, h2, h3, h4, h5, h6 { font-weight: bold; }
h1 { font-size: 1.875em; line-height: 1.6em; margin-top: 2em; }
h2, h3 { font-size: 1.3125em; line-height: 1.15; margin-top: 2.285714em; margin-bottom: 1.15em; }
h3 { font-weight: normal; }
h4 { font-size: 1.125em; margin-top: 2.67em; }
h5, h6 { font-size: 1em; }
h1 { border-bottom-width: 1px; border-bottom-style: solid; margin-bottom: 1.875em; padding-bottom: 0.8125em; }
a { text-decoration: none; color: rgb(6, 85, 136); }
a:hover, a:active { text-decoration: underline; }
p, blockquote, pre.md-fences, .md-fences { margin-bottom: 1.5em; }
h1, h2, h3, h4, h5, h6 { margin-bottom: 1.5em; }
blockquote { font-style: italic; border-left-width: 5px; border-left-style: solid; margin-left: 2em; padding-left: 1em; }
ul, ol { margin: 0px 0px 1.5em 1.5em; }
ol li { list-style-type: decimal; list-style-position: outside; }
ul li { list-style-type: disc; list-style-position: outside; }
.md-meta, .md-before, .md-after { color: rgb(153, 153, 153); }
table { margin-bottom: 1.5em; font-size: 1em; }
thead th, tfoot th { padding: 0.25em 0.25em 0.25em 0.4em; text-transform: uppercase; }
th { text-align: left; }
td { vertical-align: top; padding: 0.25em 0.25em 0.25em 0.4em; }
code, pre.md-fences { background-color: rgb(218, 218, 218); padding-left: 1ch; padding-right: 1ch; }
pre.md-fences { margin-left: 2em; margin-bottom: 3em; }
pre, code, tt { font-size: 0.875em; line-height: 1.714285em; }
h1 { line-height: 1.3em; font-weight: normal; margin-bottom: 0.5em; }
p + ul, p + ol { margin-top: -1em; }
h3 + ul, h4 + ul, h5 + ul, h6 + ul, h3 + ol, h4 + ol, h5 + ol, h6 + ol { margin-top: 0.5em; }
li > ul, li > ol { margin-top: inherit; }
h2, h3 { margin-bottom: 0.75em; }
hr { border-style: none none solid; border-bottom-width: 1px; }
h1 { border-color: rgb(197, 197, 197); }
blockquote { border-color: rgb(186, 186, 186); color: rgb(101, 101, 101); }
thead.md-table-edit { background-color: transparent; }
thead { background-color: rgb(218, 218, 218); }
tr:nth-child(even) { background-color: rgb(232, 231, 231); background-position: initial initial; background-repeat: initial initial; }
hr { border-color: rgb(197, 197, 197); }
.task-list { padding-left: 1rem; }
.task-list-item { padding-left: 1.5rem; list-style-type: none; }
.task-list-item input::before { content: '√'; display: inline-block; width: 1.25rem; height: 1.5rem; vertical-align: middle; text-align: center; color: rgb(221, 221, 221); background-color: rgb(243, 242, 238); }
.task-list-item input:checked::before, .task-list-item input[checked]::before { color: inherit; }
#write pre.md-meta-block { min-height: 1.875rem; color: rgb(85, 85, 85); border: 0px; background-color: transparent; margin-left: 1em; margin-top: 1em; background-position: initial initial; background-repeat: initial initial; }
.md-image > .md-meta { color: rgb(155, 81, 70); }
.md-expand.md-image > .md-meta { background-color: rgba(255, 255, 255, 0.65098); }
.md-image > .md-meta { font-family: Menlo, 'Ubuntu Mono', Consolas, 'Courier New', 'Microsoft Yahei', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', sans-serif; }
#write > h3.md-focus::before { left: -2.5rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h4.md-focus::before { left: -2.5rem; top: 0.25rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h5.md-focus::before { left: -2.5rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h6.md-focus::before { left: -2.5rem; top: 0.3125rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
.md-toc:focus .md-toc-content { margin-top: 19px; }
.md-toc-content:empty::before { color: rgb(6, 85, 136); }
.md-toc-item { color: rgb(6, 85, 136); }
#write div.md-toc-tooltip { background-color: rgb(243, 242, 238); }
#outline-dropmenu { background-color: rgb(243, 242, 238); -webkit-box-shadow: rgba(0, 0, 0, 0.372549) 0px 6px 12px; box-shadow: rgba(0, 0, 0, 0.372549) 0px 6px 12px; }
.pin-outline #outline-dropmenu { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; box-shadow: none; border-right-width: 1px; border-right-style: dashed; background-position: inherit inherit; background-repeat: inherit inherit; }
.pin-outline #outline-dropmenu:hover .outline-title-wrapper { border-left-width: 1px; border-left-style: dashed; }
.outline-item:hover { background-color: rgb(218, 218, 218); border-left-width: 18px; border-left-style: solid; border-left-color: rgb(218, 218, 218); border-right-width: 18px; border-right-style: solid; border-right-color: rgb(218, 218, 218); }
.outline-expander::before { content: ''; font-family: FontAwesome; font-size: 14px; top: 1px; }
.outline-expander:hover::before, .outline-item-open > .outline-item > .outline-expander::before { content: ''; }
How Not to Crash #6: Properties and Accessors潜在的问题正确的方法solveExceptions使用实例变量的例外Auto-synthesize自动合成Use ARCDon’t do->thisdeallocUse weakunsafe_unretained
How Not to Crash #6: Properties and Accessors
潜在的问题
This gives me the willies:
void)someRandomMethod {
some stuff…
_thing = otherThing;
other stuff…
}
You could prove that it’s correct. You’re using ARC, so the proper retains and releases are added. And nobody is observing _thing.
Fine. It’s legal and it works.
Say you realize that thing should be observable. So every place you set thing, you bracket the call:
[self willChangeValueForKey:kThingKey];
_thing = otherThing;
[self didChangeValueForKey:kThingKey];
Also legal, also works.
The problem is the future: later today, tomorrow, or in six months, you or somebody else writes a custom setter for thing(重写了setter的时候) — maybe because you need something like self.needsDisplay = YES when thing is set — and now you have a bug where the view doesn’t redraw whenever thing changes.
Or worse: perhaps that future custom setter tears down an observer and sets up a new one whenever thing changes. Since you’re setting _thing directly, the observations won’t be maintained properly, and you’ll get crashes.
The answer is a simple rule: use the accessor when getting and setting properties.
正确的方法solve
In other words, do this:
(void)someRandomMethod {
some stuff...
self.thing = otherThing;
other stuff…
}
This works whether or not you have a custom setter. When setting thing, you don’t have to care one way or the other.
(Here’s the simple test of a programming rule: if you can’t go wrong by following it, but you can go wrong by not following it, then you should follow it.)
(Don’t worry about the performance issue of going through accessors. I’m a performance junkie, and I’ve never seen this become a problem. If your app develops performance issues, profile it and find out the real cause.)
关于使用实例变量和属性的问题,在effetive c 2.0中有更多的介绍.
Exceptions使用实例变量的例外
You should not go through the accessor in four places: init methods, dealloc, custom getter, and custom setter. This avoids side effects.
If you need a side effect — removing an observer, for instance, in dealloc — that you’d normally place in the setter, make it a separate method and call it from the setter and from dealloc. (Also consider that adding and removing observers outside of init and dealloc is a possible sign that your code needs refactoring.)
Auto-synthesize自动合成
Don’t create instance variables, ever. Declare properties instead.
Properties auto-synthesize instance variables. Use @synthesize only when Xcode tells you you need to.
Use ARC
And if you have non-ARC code, upgrade it to use ARC. Manual memory management is error-prone. Even someone with years of experience will make mistakes from time to time, and mistakes can cause crashes (or memory leaks or abandoned memory, at best).
Normally I don’t advocate editing working code that’s running fine — but if you have code that needs maintaining, do yourself and your co-workers a favor and convert it to ARC. (Everybody is going to get worse at manual memory management over time. And there are no points added for being a hero.)
(It is possible to run into performance issues with ARC, particularly if you’re dealing with lots of objects in a loop. Remember to use autorelease pools. And don’t jump to conclusions: use the profiler.)
(Also: the ARC converter may not always do what you want. If you use it, check the changes it makes. Remember that you can convert one file at a time. Targets can have both ARC and non-ARC files.)
Don’t do->this
This gives me the screaming meemies:
thing->property.
No.
dealloc
If you don’t need dealloc (since you’re using ARC), then don’t create it. There’s no need to set properties to nil in dealloc.
A big exception is delegates: nil out the delegates.
Use weak
Weak is awesome. Delegates, for instance, should be weak.
Parents should retain their children, but children should have a weak reference to their parents (if they have a reference at all). Weak gets you out of those invalidate methods where you break retain cycles.
unsafe_unretained
Do not, under any circumstances whatsoever, use unsafe_unretained. It’s a trap. You might as well do this:
define CRASHING_BUG unsafe_unretained
It’s literally called unsafe.
Don’t run with scissors. Heck — don’t even touch these scissors. They have a bunch of poison on them.
原文链接和参考译文:
How Not to Crash #6: Properties and Accessors(属性,存储器方法使问题)的更多相关文章
- springboot成神之——application.properties所有可用属性
application.properties所有可用属性 # =================================================================== # ...
- java分享第十六天( java读取properties文件的几种方法&java配置文件持久化:static块的作用)
java读取properties文件的几种方法一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取Propert ...
- 通过getResourceAsStream 获得Properties文件属性和属性值
1.Class.getResourceAsStream(String path) path:不以‘/’开头默认是从此类所在的包下取资源:以'/'开头则是从ClassPath根目录下获取 2.Class ...
- SpringBoot @Value读取properties文件的属性
SpringBoot在application.properties文件中,可以自定义属性. 在properties文件中如下示: #自定义属性 mail.fromMail.addr=lgr@163.c ...
- java读取properties文件的几种方法
一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取 Properties p=new Properties(); ...
- gradle-wrapper.properties中各属性的含义
gradle-wrapper.properties中各属性的含义 1. gradle-wrapper.properties 每一个用gradle编译的工程,都会有一个gradle\wrapper目录. ...
- properties类的基本使用方法
properties类的基本使用方法1.假设有“pp.properties”,内容有 age=22 2.java中用下面方法: Properties props = ...
- 【转载】java读取.properties配置文件的几种方法
读取.properties配置文件在实际的开发中使用的很多,总结了一下,有以下几种方法(仅仅是我知道的):一.通过jdk提供的java.util.Properties类.此类继承自java.util. ...
- SpringBoot 获取properties配置文件的属性
自定义properties文件获取属性 使用 @ConfigurationProperties((prefix = "demo")) 和 @PropertySource(" ...
随机推荐
- Git工程迁移方法总结(命令行) .(转载)
原文地址:http://blog.csdn.net/hongshan50/article/details/236630433 Git工程迁移方法总结 Git工程迁移方法总结 Git最近准备迁移一下位置 ...
- stm8时钟
为使系统快速启动,复位后时钟控制器自动使用HSI的8分频(HSI/8)做为主时钟(2M).其原因为HSI的稳定时间短,而8分频可保证系统在较差的VDD条件下安全启动.一旦主时钟源稳定,用户程序可将主时 ...
- [转]JDBC快速入门教程
JDBC是什么? JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: ...
- linux环境下matlab连接mysql
因为matlab是基于java的,但是原生的matlab是没有jdbc的,这是一个java的mysql connection. 只有matlab有这个包,才能正确的连接mysql. 1.在http:/ ...
- php分享二十六:支付系统设计
一个典型PHP支付系统的设计与实现 参考:blog.sina.com.cn/s/blog_81f6205801017ec8.html 微信支付开发: http://www.cnblogs.com/tx ...
- Android开发之API应用指南
原文:http://android.eoe.cn/topic/android_sdk 编辑流程 这里主要是和Android技术相关的开发指南,很多都是来源于官方的API Guides( http:// ...
- Android:UI 沉浸式体验,适合第一屏的引导图片、预览图片。
链接:http://www.cnblogs.com/liushilin/p/5799381.html
- 关于第三方cookie的作用域以及针对用户行为的使用
cookie,很多网站都会用的一个机制,可以保存用户的相关信息,token等等,很多人熟知的应该是第一方cookie,可以针对二级域名进行信息的保存,如果遇到跨域的情况,那么第一方cookie是没有用 ...
- [svc][jk]磁盘的iops和吞吐量(Throught)指标
参考 另参考 IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一.IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处 ...
- UIScrollView中图片放大后不居中,或居中后移动有偏差解决办法
转自:http://blog.sina.com.cn/s/blog_6ae8b50d0100yret.html 问题的描述如下:要显示一张图片,也只需要显示一张图片,该图片可能很大,也可能很小,但是要 ...