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. nginx-request_time和upstream_response_time

    1.request_time 官网描述:request processing time in seconds with a milliseconds resolution; time elapsed ...

  2. 《精通Python设计模式》学习结构型之享元模式

    这个我日常当中也没有用到过, 真的是游戏行业用得多些? 学习一下, 有个印象. import random from enum import Enum TreeType = Enum('TreeTye ...

  3. Java学习(JDBC java连接数据库)

    一.概述 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写 ...

  4. javascript json字符串转json对象方法

    /* * @method 将拼接好字符串格式的json 转成json对象 * @param jsonData param fomart: * var jsonData = "{name1:' ...

  5. C语言:奇偶归一猜想

    1.奇偶归一猜想——求多少步归一.(10分) 题目内容: 奇偶归一猜想——对于每一个正整数,如果它是奇数,则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1. 如n = 11,得 ...

  6. MVC 源码调试

    源码调试,帮助你跟好理解MVC,使你开发跟牛B的程序. 1>在Visual命令行中运行“SN.EXE-Vr*,31BF3856AD364E35” 2. codeplex.com 上面找到,和你当 ...

  7. 在VMware虚拟机中安装Mac OS 操作系统

    1. 安装VMware 我这里是安装VMWARE12.exe,其他的版本我不知道是否可以正常运行,最好大家安装12版本的比较好. 2. 安装 Mac OS X Unlocker for VMware ...

  8. 21:包含min函数的栈

    import java.util.Stack; /** * 面试题21:包含min函数的栈 * 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. */ public class ...

  9. MySQL性能优化之char、varchar、text的区别

    参考来源:https://blog.csdn.net/brycegao321/article/details/78038272 在存储字符串时, 可以使用char.varchar或者text类型, 那 ...

  10. eNSP仿真学习和VLAN配置

    路由&交换机基本命令 sys #切换到系统视图(修改配置),Ctrl+Z 返回用户视图 sysname SW1 #设备重命名为SW1 int g0/0/1 #进入接口视图 VLAN配置 首先连 ...