iOS开发中的 ARC

简介:

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:1000
            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:1000
            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:1000
            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:1000
            inQueue:dispatch_get_main_queue()
              block:^(dispatch_queue_t queue) {
                  NSLog(@"%@", str);
              }];

-__strong修饰方式-
// 赋值
    __strong NSString *str = [NSString stringWithFormat:@"strong"];
    
    // 延时1000毫秒
    [self delayTime:1000
            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:1000
            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:1000
            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:1000
            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.

目录
相关文章
|
1月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
88 3
|
3月前
|
存储 iOS开发
iOS 开发,如何进行应用的本地化(Localization)?
iOS 开发,如何进行应用的本地化(Localization)?
122 2
|
3月前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
39 0
|
3月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
93 2
|
3月前
|
API 开发工具 iOS开发
iOS 开发高效率工具包:10 大必备工具
iOS 开发高效率工具包:10 大必备工具
48 1
|
3月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
54 1
|
8天前
|
API 定位技术 iOS开发
IOS开发基础知识:什么是 Cocoa Touch?它在 iOS 开发中的作用是什么?
【4月更文挑战第18天】**Cocoa Touch** 是iOS和Mac OS X应用的核心框架,包含面向对象库、运行时系统和触摸优化工具。它提供Mac验证的开发模式,强调触控接口和性能,涵盖3D图形、音频、网络及设备访问API,如相机和GPS。是构建高效iOS应用的基础,对开发者至关重要。
12 0
|
23天前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
2月前
|
监控 API Swift
用Swift开发iOS平台上的上网行为管理监控软件
在当今数字化时代,随着智能手机的普及,人们对于网络的依赖日益增加。然而,对于一些特定场景,如家庭、学校或者企业,对于iOS设备上的网络行为进行管理和监控显得尤为重要。为了满足这一需求,我们可以利用Swift语言开发一款iOS平台上的上网行为管理监控软件。
197 2
|
3月前
|
数据可视化 iOS开发
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
40 4