ACCESSiOS开发中之 ARC

1. weak属性(弱引用)

ACCESS 1

深受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属性(强引用)

ACCESS 2

给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」错误。

ACCESS 3

 

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.

 

 

 

 

 

相关文章