变量命名引起的血案

作者: joshualiyz | 来源:发表于2016-06-13 12:46 被阅读114次

前两天发现一个很诡异的crash bug,log如下:
-[CFNumber release]: message sent to deallocated instance 0x163576e0
log清楚的告诉我们,这是一个野指针。ARC里也有野指针?!只是我们遇到的太少了,所以忽略了这个问题。仔细追查下去,发现是某一个变量名字是new开头引起的。苹果的官方文档很清楚的告诉我们不能这样做:

To allow interoperation with manual retain-release code, ARC imposes a constraint on method naming:
You cannot give an accessor a name that begins with new. This in turn means that you can’t, for example, declare a property whose name begins with new unless you specify a different getter:

// Won't work:
@property NSString *newTitle;
 // Works:
@property (getter=theNewTitle) NSString *newTitle;

但是并不是所有的变量都不能用new开头,上面说的很清楚,这个限制是加在method naming的,之所以变量不能以new开头,是因为变量自动生成的getter方法违反了上述规则。所以,如果我们声明的是基本类型,你用new开头命名是没有问题的。

一般情况下,我们不用担心这个问题,因为(不知道从那个版本开始)Xcode7已经很好的帮我们做了这件事情:

编译错误

但是,坑就坑在Category中的变量并不会报编译错误。****最容易忽略的case就是CoreData。****笔者遇到的问题就是CoreData一个属性用了new开头的命名方式。
解决方案很简单,修改命名方式即可。

但是

****这样的命名方式为什么会产生一个野指针?****
其实换个角度更好理解这个问题,就是我们多调用了一次release。在ARC中,release都是由编译器来处理的,翻翻clang的文档看看能不能找到些帮助。

Semantics of method families

A method’s membership in a method family may imply non-standard semantics for its parameters and return type.
Methods in the alloc, copy, mutableCopy, and new families — that is, methods in all the currently-defined families except init — implicitly return a retained object as if they were annotated with the ns_returns_retained attribute. This can be overridden by annotating the method with either of the ns_returns_autoreleased or ns_returns_not_retained attributes.
Properties also follow same naming rules as methods. This means that those in the alloc, copy, mutableCopy, and new families provide access to retained objects. This can be overridden by annotating the property with ns_returns_not_retained attribute.

Retained return values

A function or method which returns a retainable object pointer type may be marked as returning a retained value, signifying that the caller expects to take ownership of a +1 retain count. This is done by adding the ns_returns_retained attribute to the function or method declaration, like so:

id foo(void) __attribute((ns_returns_retained));
- (id) foo __attribute((ns_returns_retained));

This attribute is part of the type of the function or method.
When returning from such a function or method, ARC retains the value at the point of evaluation of the return statement, before leaving all local scopes.
When receiving a return result from such a function or method, ARC releases the value at the end of the full-expression it is contained within, subject to the usual optimizations for local values.

StackOverFlow中的回答概括下
methods that start with new are assumed to return an object that ARC is responsible for managing and releasing

参考内容:
Semantics of method families
Retained return values
StackOverFlow

相关文章

  • 变量命名引起的血案

    前两天发现一个很诡异的crash bug,log如下:-[CFNumber release]: message s...

  • JULIA-值域

    值域,变量的作用域。是变量有效区域,每一种高级语言,都会对变量作用域做出定义,以规范变量命名规则,避免变量命名引起...

  • C++ 项目相关知识命名空间

    命名空间 命名空间一般是对全局变量,函数,类做处理的,以防多个重名变量引起的重定义错误。命名空间主要分为三种 你指...

  • 变量命名规范

    变量命名的目的:提高可读性 普通变量命名 循环变量命名 状态变量命名 布尔变量命名 临时变量命名 枚举类型命名 变...

  • 阿里巴巴java开发者手册整理(一)

    编程规约命名风格:驼峰命名POJO类中布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误;例如: 定义...

  • WindowManager 引起的血案

    最近在一个项目时,需要在手机的底部显示一个floatview,大致流程是: ActivityA -> 点击按...

  • Javascript 的全局变量和namespace

    全局变量的使用应该引起注意,只有系统范围相关的对象才声明为全局变量, 并且避免命名冲突。 比较好的减少全局变量的策...

  • Web前端学习基础之JavaScript命名空间

    在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量不是按照想像中的顺序来。避免全局变量名冲突的...

  • AppleScript 基础(一)基本语法和数据类型

    AppleScript 基础 一、基本语法 在 AppleScript 中所有值都需要使用双引号引起来。 变量命名...

  • 90.读鸟哥私房菜3|学习shell脚本2

    例子 使用日期命名文件 变量赋值:等号左右不能有空格如果值中有空格,要用引号把值引起来 输出变量的值:echo $...

网友评论

    本文标题:变量命名引起的血案

    本文链接:https://www.haomeiwen.com/subject/nujydttx.html