1. weak属性(弱引用)

被weak修饰的对象叫弱引用,不算对象持有者,一个方法执行完后会导致这个对象自动释放掉,并将对象的指针设置成nil,我使用GCD延时1000ms来验证,1000ms之后,其对象是否还在.

#import "RootViewController.h"

@interface RootViewController ()

@property (nonatomic, weak) NSString *str;

@end

@implementation RootViewController

/**
延时多少毫秒 @param microseconds 毫秒
@param queue 线程池
@param block 执行代码处
@return none
*/
- (void)delayTime:(int64_t)microSeconds inQueue:(dispatch_queue_t)queue
block:(void (^)(dispatch_queue_t queue))block
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, microSeconds * USEC_PER_SEC);
dispatch_after(popTime, queue, ^(void){
block(queue);
});
} - (void)viewDidLoad
{
[super viewDidLoad]; // 赋值
_str = [NSString stringWithFormat:@"weak"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", _str);
}];
} @end

打印信息:

2014-03-31 14:48:29.360 ARC[3387:60b] (null)

被__weak修饰的对象也是弱引用,如下所示,其打印信息也为nil

    // 赋值
__weak NSString *str = [NSString stringWithFormat:@"weak"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", str);
}];

2. strong属性(强引用)

被strong修饰的对象叫强引用,是对象持有者,一个方法执行完后这个对象不会被释放,我使用GCD延时1000ms来验证,1000ms之后,其对象是否还在.

#import "RootViewController.h"

@interface RootViewController ()

@property (nonatomic, strong) NSString *str;

@end

@implementation RootViewController

/**
延时多少毫秒 @param microseconds 毫秒
@param queue 线程池
@param block 执行代码处
@return none
*/
- (void)delayTime:(int64_t)microSeconds inQueue:(dispatch_queue_t)queue
block:(void (^)(dispatch_queue_t queue))block
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, microSeconds * USEC_PER_SEC);
dispatch_after(popTime, queue, ^(void){
block(queue);
});
} - (void)viewDidLoad
{
[super viewDidLoad]; // 赋值
_str = [NSString stringWithFormat:@"strong"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", _str);
}];
} @end

打印信息:

2014-03-31 14:59:57.445 ARC[3599:60b] strong

默认方式创建的对象以及__strong方式修饰的对象都是强引用,其打印信息是"strong"

-默认方式-

    // 赋值
NSString *str = [NSString stringWithFormat:@"strong"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", str);
}];

-__strong修饰方式-

    // 赋值
__strong NSString *str = [NSString stringWithFormat:@"strong"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", str);
}];

strong修饰的对象没有释放,则weak还是可以用的

    // 赋值
NSString *str = [NSString stringWithFormat:@"strong"];
__weak NSString *tmp = str; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", tmp);
NSLog(@"%@", str);
}];

打印信息:

2014-03-31 15:27:48.894 ARC[4144:60b] strong
2014-03-31 15:27:48.897 ARC[4144:60b] strong

以下例子按理说stringTest中retStr属于强引用,但其值赋给tmp时,却打印为nil,为什么呢?

ARC下,当一个函数返回一个NSObject指针时,编译器会帮我们实现autorelease调用,也就是retStr与返回值不是一个东西了.

- (void)viewDidLoad
{
[super viewDidLoad]; // 赋值
NSString *str = [NSString stringWithFormat:@"strong"];
__weak NSString *tmp = [self stringTest]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", tmp);
NSLog(@"%@", str);
}];
} - (NSString *)stringTest
{
__strong NSString *retStr = [NSString stringWithFormat:@"strongVer2"]; // 延时1000毫秒
[self delayTime:
inQueue:dispatch_get_main_queue()
block:^(dispatch_queue_t queue) {
NSLog(@"%@", retStr);
}]; return retStr;
}

打印信息:

2014-03-31 15:30:19.185 ARC[4172:60b] strongVer2
2014-03-31 15:30:19.188 ARC[4172:60b] (null)
2014-03-31 15:30:19.188 ARC[4172:60b] strong

3. __unsafe_unretained

该关键字与__weak一样,也是弱引用,与__weak的区别只是是否执行nil赋值。需要注意变量所指的对象已经被释放了,但地址还存在,如果还是访问该对象,将引起「BAD_ACCESS」错误。

4. __autoreleasing

本人并没有明白__autoreleasing有什么作用,看例子也没明白,提供链接供读者参考

http://stackoverflow.com/questions/20949886/need-more-explanation-on-usage-of-autoreleasing

'm desperately trying to understand the usage of __autoreleasing keyword in Objective-C. I have thoroughly read answers to the following questions:

In which situations do we need to write the __autoreleasing ownership qualifier under ARC?

Use of __autoreleasing in code snippet example

NSError and __autoreleasing

问:非arc项目中使用了arc编译的静态库,为什么不会报警告?

http://stackoverflow.com/questions/18609935/strong-qualifier-used-in-non-arc-project

The project is non-ARC enabled, however we are (mistakingly) using ARC compliant code libraries - specifically one to create singleton objects like so defined in GCDSingleton.h:

我的项目是非arc的,然而,我无意间使用了用arc编译的库,尤其是其中的一个单例对象,在GCDSingleton.h文件中定义的:

#define DEFINE_SHARED_INSTANCE
+(id)sharedInstance
{staticdispatch_once_t pred =0;
__strong
static id _sharedObject = nil;
dispatch_once(&pred,^{
_sharedObject =^{return[[self alloc] init];}();});return _sharedObject;}

This seems to work even though the shared object is defined with an __strong qualifier. I'm wondering why this doesn't cause an error or at least a warning (latest Xcode 4.6 and ios 6 sdk). Also, since the project is not ARC enabled, what exactly is that __strong qualifier doing, if anything?

即使这个对象被定义成了__strong,但还是可以使用.我在想,为什么不会引起一个警告.__strong在非arc项目中到底做了什么,任何一点解释都行.

------------------------------------------------------------------------------------------------------------------

In MRC code, __strong is simply ignored.

在非arc代码中,__strong被忽略掉了.

I tried to compile a simple example

#import <Foundation/Foundation.h>

int main(int argc,charconst*argv[]){
__strong NSString* foo =[[NSString alloc] initWithFormat:@"Hello, %s", argv[1]];
NSLog(@"%@", foo);
}

with ARC

clang -fobjc-arc test.m -S -emit-llvm -o arc.ir

and without ARC

clang -fno-objc-arc test.m -S -emit-llvm -o mrc.ir

and to diff the llvm IR output.

Here's the result of diff mrc.ir arc.ir

54a55,56>%17= bitcast %0**%foo to i8**>   call void@objc_storeStrong(i8**%17, i8* null) nounwind
63a66,67> declare void@objc_storeStrong(i8**, i8*)>

So basically the only difference between ARC and MRC is the addition of a objc_storeStrong call.


By the way the same code without the __strong qualifier will produce the same exact results, since __strong is the default qualifier for variables in ARC.

iOS开发中的 ARC的更多相关文章

  1. iOS开发中调试小技巧

    对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...

  2. 多线程在iOS开发中的应用

    多线程基本概念 01 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 02 线程 2-1 基本概念 1个进程要想执行任务,必须得有线程 ...

  3. 在iOS开发中使用FMDB

    在iOS开发中使用FMDB 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK 很早就支持了 SQLite,在使用时,只需 ...

  4. iOS 开发中的单例

    在iOS开发中经常会用到单例,比如每个iOS程序本身就是一个单例,在比如进行个人偏好设置存储的时候用的也是一个单例.那我们如何自己来写一个单例类呢,用自己的单例对象呢?下面是我写的一个单例的头文件里的 ...

  5. 【转】在iOS开发中使用FMDB

    本文转载自:唐巧的博客 在iOS开发中使用FMDB APR 22ND, 2012 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iO ...

  6. iOS开发中的压缩以及解压

    事实上,在iOS开发中,压缩与解压,我都是采用第三方框架SSZipArchive实现的 gitHub地址:   https://github.com/ZipArchive/ZipArchive 上面有 ...

  7. iOS开发中各种关键字的区别

    1.一些概念 1.浅Copy:指针的复制,只是多了一个指向这块内存的指针,共用一块内存. 深Copy:内存的复制,两块内存是完全不同的, 也就是两个对象指针分别指向不同的内存,互不干涉. 2.atom ...

  8. iOS - 开发中调试小技巧

    对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...

  9. [转载]对iOS开发中内存管理的一点总结与理解

    对iOS开发中内存管理的一点总结与理解   做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...

随机推荐

  1. BFC 从了解到放弃

    最近工作中我突然产生了一个想法,就如我们人类面临的终极问题一般,我从哪里来?我到哪里去?在撸代码进行CSS布局的时候,我会去想,我为什么这么做?,为什么浮动的元素要用overflow?,为什么要用cl ...

  2. HTTPS、SPDY和HTTP/2的性能比较

    http://www.infoq.com/cn/news/2015/02/https-spdy-http2-comparison/ https://segmentfault.com/a/1190000 ...

  3. servlet 学习笔记(二)

    ---------------------第二讲--------------------------------- 开发servlet有三种方法: 1.实现servlet接口(最原始的) 实现接口的5 ...

  4. 基于范围的for循环

    语法: for ( for-range-declaration : expression ) statement 注意一般用auto表达类型.不需要修改时常用引用类型 例子: // range-bas ...

  5. atomikos + druid 连接超时失效

    atomikos + druid 连接超时失效,需要多次连接才能成功. 首次连接会报异常: 2018-01-08 16:58:12 DEBUG [com.jpcar.model.dao.jpcar.A ...

  6. Bomb HDU 3555 dp状态转移

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题意: 给出一个正整数N,求出1~N中含有数字“49”的数的个数 思路: 采用数位dp的状态转移方程 ...

  7. URL的组成

    饮水思源 http://blog.csdn.net/ergouge/article/details/8185219 http://www.cnblogs.com/kaituorensheng/p/37 ...

  8. poj3349(hash table)

    做的第一道哈希表的题目.速度很慢,跑了3000+ms.采用六条边的和对一个大质数的余数作为哈希表的key,理论上质数取得越大,消耗的空间就越大,但是速度会加快,这里取了14997.地址冲突用链表解决. ...

  9. Swift2.0语言教程之下标脚本

    Swift2.0语言教程之下标脚本 下标脚本 下标脚本是访问对象.集合或者序列的快速方式.开发者不需要调用实例特定的赋值和访问方法,就可以直接访问所需要的数值.例如在数组中,可以直接使用下标去访问或者 ...

  10. 深入理解ajax系列第七篇

    前面的话 虽然ajax全称是asynchronous javascript and XML.但目前使用ajax技术时,传递JSON已经成为事实上的标准.因为相较于XML而言,JSON简单且方便.本文将 ...