今天和同事在处理一处用strong声明的Block属性引发的问题时偶然发现的。在诸多教程中都会讲到:声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strongretain会有截然不同的效果。strong会等于copy,而retain竟然等于assign

当然定义Block还是应该用copy(还有其他需要注意的地方,可以参考这篇文章:iOS: ARC和非ARC下使用Block属性的问题),因为非ARC下不copy的Block会在栈中,ARC中的Block都会在堆上的。

可以这样复现问题。在非ARC环境下,定义一个简单类型,定义一个Block属性,先用正确的copy

 @interface TestCls : NSObject

 @property (nonatomic, copy) void(^myBlock)();

 @end

在另一个类型里声明变量:

  TestCls *_testObj 

然后在一个方法里,比如viewDidLoad中,设置Block变量,注意即便是在非ARC下,没有引用外部变量的Block类型也是__NSGlobalBlock__,而引用外部变量的Block才是__NSStackBlock__,如下代码:

 _testObj = [[TestCls alloc] init];

 int outerVar = ;

 _testObj.myBlock = ^void()
{
NSLog(@"Block被调用:%d", outerVar);
};
NSLog(@"Block类型:%@", [_testObj.myBlock class]);

然后在另一个方法里(比如UIButton的点击事件方法里)去执行Block,如下:

  _testObj.myBlock();  

测试环境是Xcode 6/iOS 7/8,如果最上面myBlock属性声明是copy或者strong的话,Block都会被copy,输出:

 Block类型:__NSMallocBlock
__ Block被调用: 

如果上面myBlock属性声明是retain或者assign的话,Block表现起来就是assign,没有去copy,输出:

 Block类型:__NSStackBlock__ 

此时可能会Crash(BAD_ACCESS),也有可能输出错误的值(我在控制台下测试会出现这种情况)。因为Block作用域在函数栈里,而函数已经执行完毕了。

总之,strongretain竟然有不一样的地方,而声明Block属性请务必用copy

 

iOS: 属性声明strong和retain竟然不一样的更多相关文章

  1. iOS的属性声明:retain和strong的区别

    声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong).不过在声明Block时,使用strong和retain会有截然不同的效果.strong会等于copy,而r ...

  2. IOS—— strong weak retain assign 学习

    转自:http://wenzongliang.iteye.com/blog/1746604 简单讲strong等同retain weak比assign多了一个功能,当对象消失后自动把指针变成nil,好 ...

  3. iOS - property,strong,weak,retain,assign,copy,nomatic 的区别及使用

    1:ARC环境下,strong代替retain.weak代替assign,xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和assign,是不支持ARC的.xcod ...

  4. iOS:不同属性声明方式的解析

    代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因 ...

  5. iOS 内存管理-copy、 retain、 assign 、readonly 、 readwrite、nonatomic、@property、@synthesize、@dynamic、IB_DESIGNABLE 、 IBInspectable、IBOutletCollection

    浅谈iOS内存管理机制 alloc,retain,copy,release,autorelease 1)使用@property配合@synthesize可以让编译器自动实现getter/setter方 ...

  6. NSMutable属性声明时为什么不能使用copy

    在iOS开发里面我们经常会进行NSMutable(可变类型的类,常用的如NSMutableString,NSMutableArray,NSMutableDictionary,NSMutableData ...

  7. iOS 属性修饰符记录 --不定时更新

    重新审视了一下OC在属性修饰符,特意记录一下来.以后不定时更新 > retain:只有在非ARC下才会有效,所有如果在ARC下使用了retain修饰也白搭 如以下的data属性用retain修饰 ...

  8. 字符串属性使用strong的原因

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  9. HTML编码规则、CSS属性声明顺序--简介

    From AmazeUI:http://amazeui.org/getting-started/html-css-guide HTML 属性顺序 HTML 属性应当按照以下给出的顺序依次排列,确保代码 ...

随机推荐

  1. HTML的奇葩嵌套规则

    一.HTML 标签包括 块级元素(block).内嵌元素(inline) 1.块级元素 一般用来搭建网站架构.布局.承载内容……它包括以下这些标签: address.blockquote.center ...

  2. windows7+eclipse-jee-luna+hadoop2.6运行环境及eclipse plugin插件编译

    一.hadoop集群环境配置  参见:<Hadoop2.6集群环境搭建(HDFS HA+YARN)原来4G内存也能任性一次.> Win7环境: 登录用户名:hadoop , 与Hadoop ...

  3. MapReduce的执行过程.

    作业在运行时,数据或者是作业调用的一个运行图. 用户写的代码通过JobClient提交给JobTracker Job对象中封装了JobClient JobConf和我们的Job对象几乎是一回事. 把我 ...

  4. Codeforces 377

    简单说一下. A 搜索出任意一个剩余细胞个数的联通块.剩下的填X. B 二分加贪心加数据结构. /* * Problem: * Author: Shun Yao */ #include <str ...

  5. linux内核书籍

    1, 关于操作系统理论的最初级的知识.不需要通读并理解<操作系统概念><现代操作系统>等巨著,但总要知道分时(time-shared)和实时(real-time)的区别是什么, ...

  6. 用一个例子学习CSS的伪类元素

    CSS伪类元素是一个非常酷的东西!首先我们理解一下它,:before :after 伪类元素,也就是虚假的元素.它可以插入在元素的前面或者后面,而在HTML文档结构中,它却是不存在的,因为Js是无法通 ...

  7. Hibernate之Session对象的相关方法以及持久化对象的状态

    一.持久化对象的状态        站在持久化的角度, Hibernate 把对象分为 4种状态: 持久化状态,临时状态,游离状态,删除状态.Session 的特定方法能使对象从一个状态转换到另一个状 ...

  8. Java邮件服务学习之五:邮箱服务服务端 Apache

    Apache James(Java Apache Mail Enterprise Server)是Apache组织的子项目之一,完全采用纯Java技术开发,实现了SMTP.POP3与NNTP等多种邮件 ...

  9. Spring JdbcTemplate Querying examples

    Here are few examples to show you how to use JdbcTemplate query() methods to query or extract data f ...

  10. Linux的运行级别和chkconfig用法

    Linux的运行级别和chkconfig用法        一.Linux的运行级别 在装MySQL的时候,才知道了Linux的运行级别这么一回事.汗…自己太水了…下面总结一下: 什么是运行级别呢?简 ...