iOS: 属性声明strong和retain竟然不一样
今天和同事在处理一处用strong声明的Block属性引发的问题时偶然发现的。在诸多教程中都会讲到:声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strong和retain会有截然不同的效果。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作用域在函数栈里,而函数已经执行完毕了。
总之,strong和retain竟然有不一样的地方,而声明Block属性请务必用copy。
iOS: 属性声明strong和retain竟然不一样的更多相关文章
- iOS的属性声明:retain和strong的区别
声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong).不过在声明Block时,使用strong和retain会有截然不同的效果.strong会等于copy,而r ...
- IOS—— strong weak retain assign 学习
转自:http://wenzongliang.iteye.com/blog/1746604 简单讲strong等同retain weak比assign多了一个功能,当对象消失后自动把指针变成nil,好 ...
- iOS - property,strong,weak,retain,assign,copy,nomatic 的区别及使用
1:ARC环境下,strong代替retain.weak代替assign,xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和assign,是不支持ARC的.xcod ...
- iOS:不同属性声明方式的解析
代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因 ...
- 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方 ...
- NSMutable属性声明时为什么不能使用copy
在iOS开发里面我们经常会进行NSMutable(可变类型的类,常用的如NSMutableString,NSMutableArray,NSMutableDictionary,NSMutableData ...
- iOS 属性修饰符记录 --不定时更新
重新审视了一下OC在属性修饰符,特意记录一下来.以后不定时更新 > retain:只有在非ARC下才会有效,所有如果在ARC下使用了retain修饰也白搭 如以下的data属性用retain修饰 ...
- 字符串属性使用strong的原因
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- HTML编码规则、CSS属性声明顺序--简介
From AmazeUI:http://amazeui.org/getting-started/html-css-guide HTML 属性顺序 HTML 属性应当按照以下给出的顺序依次排列,确保代码 ...
随机推荐
- C语言-简单哈希表(hash table)
腾讯三面的时候,叫我写了个哈希表,当时紧张没写好···结果跪了··· 回来后粪发涂墙,赶紧写了一个! 什么都不说了···先让我到厕所里面哭一会··· %>_<% 果然现场发挥,以及基础扎实 ...
- Tkinter教程之Entry篇
本文转载自:http://blog.csdn.net/jcodeer/article/details/1811302 #Tkinter教程之Entry篇#Entry用来输入单行文本'''1.第一个En ...
- Handler笔记
5.Handler内存泄露 在一个Activity里面,如果没有静态地创建一个Handler,有可能导致内存泄露. 因为Hander和Looper绑定,如果looper的MessageQueue有消息 ...
- display:none;与visibility:hidden;的区别
visibility:隐藏对应的元素但不挤占该元素原来的空间.display:隐藏对应的元素并且挤占该元素原来的空间. 下面来看visibility和dispaly的一些参数 visibility用来 ...
- 利用WPF创建含多种交互特性的无边框窗体
咳咳,标题一口气读下来确实有点累,让我先解释一下.另外文章底部有演示程序的下载. 本文介绍利用WPF创建一个含有以下特性的窗口: 有窗口阴影,比如QQ窗口外围只有几像素的阴影: 支持透明且无边框,为了 ...
- MES生产日报存储过程
USE [ScreenMonitor]GO/****** Object: StoredProcedure [dbo].[ImportProductForDay] Script Date: 04/11/ ...
- 部署应用程序脚本+GUIRunOnce命令
部署应用程序脚本: 应用程序配置:运行脚本(cmd.exe): 可执行程序:cmd.exe 参数: /c net user ppc boc.123 /add 运行方式账户: NT AUT ...
- Weka – 分类
1. weka简单介绍 1) weka是新西兰怀卡托大学WEKA小组用JAVA开发的机器学习/数据挖掘开源软件. 2) 相关资源链接 http://sourceforge.net/pro ...
- 【转】selenium简介及安装方法
转自:http://www.cnblogs.com/fnng/p/3157639.html 1. selenium 介绍 selenium 是一个web 的自动化测试工具,不少学习功能自动化的同学开始 ...
- Swift学习笔记七
控制流 Swift提供了和C类似的控制流表达式,包括for.while.if.switch.当然也包括break和continue这种语句来引导控制流到某个指定点的语句. 在C的for基础上,Swif ...