.h文件中:

1,@property (strong,nonatomic)中属性的定义主要是类对外的接口,将retain,copy等变为strong。

2,私有变量

.m文件中的类扩展定义的私有属性变量,即@interface class (){@property()nsarray *

array;}

现在直接在类实现中@implementation class{ nsarray *

array;}即可----附:此处仍然可以self.array来访问。

3,outlet

除了files owner(链接nib顶层对象用strong)之外,均用weak。

优势:unload中,不需要self.outlet=nil;了。

附:当接受到内存警告时,ViewCtl的mainView会unload,释放其所有subView。但是需要设置所有非outlet变量为nil。

4,strong=retain,weak(outlet多用),unsafe_unretained=assign(IOS4适用),copy=copy+strong,assign(原始类型BOOL,int,CGFloat等),readonly要+strong,iddelegate用weak,nonatomic,block用copy。

5,在.m文件中,移除所有的autorelease,retain,release调用。

诸如:self.XX=[[[mainVC

alloc]init]autorelease];现在改为:self.XX=[[mainVC alloc]init]即可。

6,dealloc{},移除所有release方法,【super

dealoc】;其他资源如定时器,CF对象时才需要之。CFRealse等。作用:1,移除监听;2,取消注册通知;3,将non-weak

delegate设置为nil;4,invalidate

timers。

7,@autoreleasepool用法:

if someArray很大

for(id obj in

someArray)

{

@autoreleasepool

{

//假如你创建了许多中间临时变量在此处

}

}

8,某个项目中若设置某个文件不使用arc,方法:在Build Phases -> Compile sources,选择需要的文件,在右边Compile Flags输入-fno-objc-arc

启用arc:-fobjc-arc

9,Blocks:主要在于blocks中的循环参照问题。

a,block在属性定义的时候,使用copy。

调用端如下:

MyObject *object = [[MyObject alloc] init]; object.str = @"hoge"; object.block = ^{NSLog(@"block:

str=%@", object.str); }; [object performBlock];

由上可知:object和block构成了循环参照,如图:

解决办法:

1,使用__block修饰---

使用__block关键字,让对象有读写权限,如果Block内的处理完毕就释放object。

__block MyObject *object = [[MyObject alloc] init]; object.str = @"hoge"; object.block= ^{ NSLog(@"block:

str=%@", object.str); object = nil; }; [object performBlock];

关键字的意思就是让block取消对object的强参照,以避免循环参照。但是,有一个问题就是,object的释放动作是在Block内部执

行,如果Block没有被执行的话,循环参照一直存在。比如上面的代码,如果第8行 [object performBlock];

没有执行的话,那么一直还是循环参照状态。

使用__weak关键字修饰

另一种方案就是让Block的参照变为弱参照。

MyObject *object = [[MyObject alloc] init]; object.str = @"hoge"; __weak MyObject*weakObject = object; object.block = ^{ NSLog(@"block:

str=%@", weakObject.str); };[object performBlock];

考虑到异步通信时Blocks的使用情况,weak变量weakObject有可能随时变为nil,所以类似于下面先变为strong变量,并检查是否为nil的处理方式应该更安全。

MyObject *object = [[MyObject alloc] init]; object.str = @"hoge"; __weak MyObject*weakObject = object; object.block = ^{ MyObject strongObject = weakObject; if(strongObject) { NSLog(@"block:

str=%@", strongObject.str); } }; [objectperformBlock];

总上,当我们使用Blocks时,也需要考虑Block中变量和实例的关系,不要引起不必要的循环参照问题。

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

以下未细化:

手动下的情况:

1,凡用alloc/new/copy/mutableCopy,则生成对象并拥有其所有权;

2,retain-拥有对象所有权,release-释放对象所有权,dealloc-释放对象资源。

3,变成准则:

生成对象时,使用autorelease-->返回对象即return [[object retain]

autorelease];

对象代入时,先autorelease再retain-->代入对象即

- (void)setMember:(TempValue *)value {

[_member autorelease];

_member = [value retain];

}

ARC开启:

1,指针在,obj就在。

2,父Var-->子Var :strong引用;子Var-->父Var :Weak引用

3,在手动惯例内存时,一旦obj自array中remove后,obj便会销毁。但在ARC中,obj拥有该值的strong引用--

{id obj = [array objectAtIndex:0];

[array removeObjectAtIndex:0];

NSLog(@"%@", obj);

}

ARC规则:

1,不能使用NSAutoReleasePool、而需要@autoreleasepool块

2,retain, release,

autorelease, dealloc由编译器自动插入,不能在代码中调用,

dealloc虽然可以被重载,但是不能调用[super dealloc]。

引用关键字:

1,strong, weak,

autoreleasing限定的变量会被隐式初始化为nil。

2,_strong:(缺省)

3,_weak

4,_unsafe_unretained:其修饰的,当无所有者时,其不自动指向nil。

5,_autoreleasing:该关键字使对像延迟释放。比如你想传一个未初始化的对像引用到一个方法当中,在此方法中实例化此对像,那么这种情况可以使用__autoreleasing。他被经常用于函数有值参数返回时的处理.

例:- (void)

generateErrorInVariable:(__autoreleasing NSError

**)paramError

{ ....

*paramError =

[[NSError alloc] initWithDomain:@"MyApp" code: 1userInfo:errorDictionary];

}

应用

{ NSError *error = nil;

[selfgenerateErrorInVariable:&error];

NSLog(@"Error = %@", error); }

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

函数的返回值是在函数中申请的,那么希望释放是在调用端时:

例:-(NSString

*)stringTest

{ NSString *retStr = [NSString

stringWithString:@"test"];

return [[retStr

retain] autorelease];

}

// 使用ARC

-(NSString *)stringTest

{

__autoreleasing NSString *retStr =

[NSString alloc]  initWithString:@"test"];

returnretStr;

}

即当方法的参数是id*,且希望方法返回时对象被autoreleased,那么使用该关键字。

----

基本的ARC使用规则

代码中不能使用retain, release,

retain, autorelease

不重载dealloc(如果是释放对象内存以外的处理,是可以重载该函数的,但是不能调用[super dealloc])

不能使用NSAllocateObject,

NSDeallocateObject

不能在C结构体中使用对象指针

id与void *间的如果cast时需要用特定的方法(__bridge关键字)

不能使用NSAutoReleasePool、而需要@autoreleasepool块

不能使用“new”开始的属性名称 (如果使用会有下面的编译错误”Property’s synthesized getter follows

Cocoa naming convention for returning ‘owned’ objects”)

----

ARC之@property

属性值

关键字

所有权

strong

__strong

weak

__weak

unsafe_unretained

__unsafe_unretained

copy

__strong

assign

__unsafe_unretained

retain

__strong

1,weak:delegate和IBOutlet用该属性来声明

2,assign:一般数据变量,BOOL

3,unsafe_unretained等价weak。

4,readwrite和readonly-----需要类似@property

(nonatomic, strong, readonly) NSString *name;

typedef void(^MyBlock)(void);

@interface MyObject :

NSObject

@property (nonatomic,copy) MyBlock

block;

@property (nonatomic, strong) NSString

*str;

-(void)performBlock;

@end

@implementation MyObject

@synthesize block, str;

-(void)performBlock

{

if

(self.block)

{ self.block(); }

}

@end

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

实用性:

1,基本var用assign:

@property (nonatomic, assign) int scalarInt;

2,对象var用strong,weak:

@property (nonatomic, strong) id childObject;

@property (nonatomic, weak) id parentObject;

@property (nonatomic, weak) NSObject *delegate;

注意:IBOutlets均设定为weak,除了top-level

IBOutlets用strong外。

3,blocks对象用copy:

@property (nonatomic, copy) SomeBlockType

someBlock;

4,在dealloc中主要任务:

{

1,移除observers;

2,unregister for notifications

3,set any non-weak delegates to nil;

4,invalidate any timers

}

5,Bridging:

id my_id;

CFStringRef my_cfref;

NSString  *a = (__bridge

NSString*)my_cfref;  // Noop

cast.

CFStringRef b = (__bridge

CFStringRef)my_id; // Noop cast.

NSString  *c = (__bridge_transfer

NSString*)my_cfref; // -1 on the CFRef

CFStringRef d = (__bridge_retained

CFStringRef)my_id; // returned CFRef +1

---------

Core Foundation框架 (CoreFoundation.framework)

是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能。Core

Foundation框架和Foundation框架紧密相关,它们为相同功能提供接口,但Foundation框架提供Objective-C接口。如果您将Foundation对象和Core

Foundation类型掺杂使用,则可利用两个框架之间的 “toll-free bridging”。所谓的Toll-free

bridging是说您可以在某个框架的方法或函数同时使用Core Foundatio和Foundation

框架中的某些类型。很多数据类型支持这一特性,其中包括群体和字符串数据类型。每个框架的类和类型描述都会对某个对象是否为

toll-free bridged,应和什么对象桥接进行说明。

自 Xcode4.2

开始导入ARC机制后,为了支持对象间的转型,Apple又增加了许多转型用的关键字。这一讲我们就来了解其用法,以及产生的理由。

引子我们先来看一下ARC无效的时候,我们写id类型转void*类型的写法:

id obj = [[NSObject alloc] init];void *p =

obj;反过来,当把void*对象变回id类型时,只是简单地如下来写,

id obj = p;[obj

release];但是上面的代码在ARC有效时,就有了下面的错误:

error:

implicit conversion of an Objective-C

pointer to

’void *’ is disallowed with

ARC void

*p =

obj; ^ error:

implicit conversion of a non-Objective-C

pointer type

’void *’ to ’id’ is disallowed with

ARC id

o =

p; ^

__bridge为了解决这一问题,我们使用 __bridge

关键字来实现id类型与void*类型的相互转换。看下面的例子。

id obj = [[NSObject alloc]

init]; void *p = (__bridge void

*)obj; id o = (__bridge id)p;将Objective-C的对象类型用

__bridge 转换为 void* 类型和使用 __unsafe_unretained

关键字修饰的变量是一样的。被代入对象的所有者需要明确对象生命周期的管理,不要出现异常访问的问题。

除过 __bridge 以外,还有两个 __bridge 相关的类型转换关键字:

__bridge_transfer__bridge_retained接下来,我们将看看这两个关键字的区别。

__bridge_retained先来看使用

__bridge_retained 关键字的例子程序:

id obj = [[NSObject alloc]

init]; void *p = (__bridge_retained void

*)obj;从名字上我们应该能理解其意义:类型被转换时,其对象的所有权也将被变换后变量所持有。如果不是ARC代码,类似下面的实现:

id obj = [[NSObject alloc]

init]; void *p = obj;[(id)p

retain];可以用一个实际的例子验证,对象所有权是否被持有。

void *p =

0; { id

obj = [[NSObject alloc]

init]; p

= (__bridge_retained void

*)obj;} NSLog(@"class=%@", [(__bridge id)p

class]);出了大括号的范围后,p 仍然指向一个有效的实体。说明他拥有该对象的所有权,该对象没有因为出其定义范围而被销毁。

__bridge_transfer相反,当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用

__bridge_transfer 关键字。文字有点绕口,我们还是来看一段代码吧。

如果ARC无效的时候,我们可能需要写下面的代码。

// p 变量原先持有对象的所有权id obj = (id)p;[obj retain];[(id)p

release];那么ARC有效后,我们可以用下面的代码来替换:

// p 变量原先持有对象的所有权id obj = (__bridge_transfer

id)p;可以看出来,__bridge_retained 是编译器替我们做了 retain 操作,而

__bridge_transfer 是替我们做了 release1。

Toll-Free bridged在iOS世界,主要有两种对象:Objective-C 对象和 Core

Foundation 对象0。Core Foundation 对象主要是有C语言实现的 Core Foundation

Framework 的对象,其中也有对象引用计数的概念,只是不是 Cocoa Framework::Foundation

Framework 的 retain/release,而是自身的 CFRetain/CFRelease 接口。

这两种对象间可以互相转换和操作,不使用ARC的时候,单纯的用C原因的类型转换,不需要消耗CPU的资源,所以叫做 Toll-Free

bridged。比如 NSArray和CFArrayRef, NSString和CFStringRef,他们虽然属于不同的

Framework,但是具有相同的对象结构,所以可以用标准C的类型转换。

比如不使用ARC时,我们用下面的代码:

NSString *string = [NSString

stringWithFormat:...];CFStringRef cfString =

(CFStringRef)string;同样,Core

Foundation类型向Objective-C类型转换时,也是简单地用标准C的类型转换即可。

但是在ARC有效的情况下,将出现类似下面的编译错误:

Cast

of Objective-C pointer type ‘NSString *’ to C pointer type

‘CFStringRef’ (aka ‘const struct __CFString *’) requires a bridged

cast Use

__bridge to convert directly (no change in

ownership) Use

__bridge_retained to make an ARC object available as a +1

‘CFStringRef’ (aka ‘const struct __CFString *’)错误中已经提示了我们需要怎样做:用

__bridge 或者

__bridge_retained 来转型,其差别就是变更对象的所有权。

正因为Objective-C是ARC管理的对象,而Core

Foundation不是ARC管理的对象,所以才要特意这样转换,这与id类型向void*转换是一个概念。也就是说,当这两种类型(有ARC管理,没有ARC管理)在转换时,需要告诉编译器怎样处理对象的所有权。

上面的例子,使用 __bridge/__bridge_retained 后的代码如下:

NSString *string = [NSString

stringWithFormat:...];CFStringRef cfString = (__bridge

CFStringRef)string;只是单纯地执行了类型转换,没有进行所有权的转移,也就是说,当string对象被释放的时候,cfString也不能被使用了。

NSString *string = [NSString

stringWithFormat:...];CFStringRef cfString = (__bridge_retained

CFStringRef)string;...CFRelease(cfString); // 由于Core

Foundation的对象不属于ARC的管理范畴,所以需要自己release使用 __bridge_retained

可以通过转换目标处(cfString)的 retain 处理,来使所有权转移。即使 string 变量被释放,cfString

还是可以使用具体的对象。只是有一点,由于Core

Foundation的对象不属于ARC的管理范畴,所以需要自己release。

实际上,Core Foundation 内部,为了实现Core

Foundation对象类型与Objective-C对象类型的相互转换,提供了下面的函数。

CFTypeRef CFBridgingRetain(id X) { return (__bridge_retained CFTypeRef)X;} id CFBridgingRelease(CFTypeRef X) { return (__bridge_transfer id)X;}所以,可以用

CFBridgingRetain 替代 __bridge_retained 关键字:

NSString *string = [NSString

stringWithFormat:...];CFStringRef cfString =

CFBridgingRetain(string);...CFRelease(cfString); // 由于Core

Foundation不在ARC管理范围内,所以需要主动release。__bridge_transfer所有权被转移的同时,被转换变量将失去对象的所有权。当Core

Foundation对象类型向Objective-C对象类型转换的时候,会经常用到 __bridge_transfer

关键字。

CFStringRef cfString = CFStringCreate...();NSString

*string = (__bridge_transfer NSString

*)cfString; // CFRelease(cfString); 因为已经用

__bridge_transfer 转移了对象的所有权,所以不需要调用 release同样,我们可以使用

CFBridgingRelease() 来代替 __bridge_transfer 关键字。

CFStringRef cfString = CFStringCreate...();NSString

*string = CFBridgingRelease(cfString);

总结由上面的学习我们了解到 ARC

中类型转换的用法,那么我们实际使用中按照怎样的原则或者方法来区分使用呢,下面我总结了几点关键要素。

明确被转换类型是否是 ARC 管理的对象Core Foundation 对象类型不在 ARC

管理范畴内Cocoa Framework::Foundation 对象类型(即一般使用到的Objectie-C对象类型)在 ARC

的管理范畴内如果不在 ARC 管理范畴内的对象,那么要清楚 release 的责任应该是谁各种对象的生命周期是怎样的1. 声明 id

obj 的时候,其实是缺省的申明了一个 __strong 修饰的变量,所以编译器自动地加入了 retain 的处理,所以说

__bridge_transfer 关键字只为我们做了 release 处理。

根据苹果官方的文档(https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html):

__bridge只做类型转换,但是不修改对象(内存)管理权;

__bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core

Foundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象;

__bridge_transfer(也可以使用CFBridgingRelease)将Core

Foundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。

-----

旧工程配置arc方案:

1、直接在targets->build

phases中修改compiler Flags,是否支持arc。添加:-fobjc-arc,就可以让旧项目支持arc。如果想让原来支持arc的不使用arc则添加-fno-objc-arc

2、因为在build

phases中可以改变是否支持arc,所以应该在代码中添加判断是否支持arc,这样不管以后.m的arc是否改变,都不用再次调整代码。

下面是一个.h文件(附件中也上传了.h),整合了arc的各种属性、release判断,直接#import在你想使用arc的类中即可。

#ifndef paixiu_PXISARC_h

#define paixiu_PXISARC_h

#ifndef PX_STRONG

#if __has_feature(objc_arc)

#define PX_STRONG strong

#else

#define PX_STRONG retain

#endif

#endif

#ifndef PX_WEAK

#if __has_feature(objc_arc_weak)

#define PX_WEAK weak

#elif __has_feature(objc_arc)

#define PX_WEAK unsafe_unretained

#else

#define PX_WEAK assign

#endif

#endif

#if __has_feature(objc_arc)

#define PX_AUTORELEASE(expression) expression

#define PX_RELEASE(expression) expression

#define PX_RETAIN(expression) expression

#else

#define PX_AUTORELEASE(expression) [expression autorelease]

#define PX_RELEASE(expression) [expression release]

#define PX_RETAIN(expression) [expression retain]

#endif

#endif

说明:在arc中,strong对应原来的retain与copy,weak对应原来的assign。

EX:举例使用autorelease:

NSArray *testArray = PX_AUTORELEASE([[NSArray alloc]

init]);

//如果支持arc,testArray就只是alloc init,release的事情由系统来做。//如果不支持arc,那这条语句相当于:NSArray *testArray = [[[NSArray alloc] init]

autorelease];

这样不管以后改不改arc,都不会内存泄漏了。

所以,arc的使用有两点:

A:在build phases中修改compiler Flags值。

B:在代码中判断是否支持arc,包括对属性(property)、释放(release)的判断。

3、在dealloc中需要这样做:

类如果注册了通知(观察者模式),需要remove掉。这个不管是否支持arc,都必须要做的。

- (void)dealloc {

[[NSNotificationCenterdefaultCenter]

removeObserver:self];//如果注册了通知的话。

[self removeObserver:self

forKeyPath:keyPath];//如果注册了kvo的话。

#if !__has_feature(objc_arc) //在这里也需要判断是否支持arc,支持的话就执行旧工程中该release的语句.

[array

release]; //array代表alloc但没有autorelease的变量

[super

dealloc];

#endif

}

4、另外加点block的判断,这个是在4.0以后有的,当然也可以不进行判断,因为现在大多数都4.0以后了。

#if NS_BLOCKS_AVAILABLE

#endif

总结:

1、arc的设置是在build phases中修改compiler

Flags的值。

2、如果使用了arc,在你的代码中不可以使用retain, release, autorelease,如果使用的话会报错。

3、如果使用了arc,在@property声明中,用strong代替retain。在支持__unsafe_unretained的情况下,__unsafe_unretained相当于assign。

4、如果使用了arc,NSAutoReleasePool也不能使用,测试发现,用@autoreleasepool 代替,不会编译报错。

总之,一切你之前“背过”的那几条内存管理规则,你都不用去管了。而且,个人感觉,用arc代码清晰很多,而且效率也提高了些。

——————————————————————————————————

对于arc属性可能写的不太清楚,这里附加点:

1、不管在不在arc下,object对象都有强引用、弱引用之分,当需要保持(拥有)其他对象的时候,需要retain。

2、在arc中,使用strong、weak修饰的变量,当对象不再存在的时候会被置为nil。而[align=-webkit-left]__unsafe_unretained不会被置为nil,会成为野指针,是不安全的,再次访问可能造成错误。

[align=-webkit-left]3,引用关键字:arc中,变量声明默认为_strong.

c语言arc函数带几个参数,ARC的使用简要总结相关推荐

  1. c语言宏函数怎么传递宏参数_C语言中的宏参数评估

    c语言宏函数怎么传递宏参数 We can define a function like Macro, in which we can pass the arguments. When a Macro ...

  2. C语言sum函数不接受一个参数,函数不接受2个参数怎么解决

    c++函数不接受两个参数是为什么 class Time { int hour,minute,second; public: Time(int a=0,int b=0,i需要在使用之前声明一下函数,你在 ...

  3. C语言 realloc函数 带着内存游走的函数

    realloc函数 realloc函数,带着内存游走的函数. 该函数将 ptr 指向的内存大小修改为size.内存中的数据从开头到size保留不变. 如果size大于原内存大小,则多出的部分会被初始化 ...

  4. main函数带命令行参数的使用

    假设程序编译后生成的可执行文件为mycal.exe..在命令行提示符下,通过在windows开始菜单执行cmd命令,出现:c:>,键入mycal 100+200 运行的结果为 300:键入myc ...

  5. C语言Arc函数画圆弧,用Canvas的arc函数绘制圆和图形

    Canvas没有circle函数来画一个圆.在Canvas绘图API中,提供了一个函数来绘制不同的弧,包括圆.arc函数可接受以下参数,具体说明参见表 把角度转换为弧度 arc函数使用的angle参数 ...

  6. R语言--rep函数

    R语言--rep函数 基础用法和参数 版权声明:本文为CSDN博主「Kalinda_yu」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明. 原文链接:https:// ...

  7. c语言中getenv的作用,C语言putenv()函数和getenv()函数的使用详解

    C语言putenv()函数和getenv()函数的使用详解 C语言putenv()函数:改变或增加环境变量头文件: #include4 定义函数: int putenv(const char * st ...

  8. C语言中函数的参数列表为空和void的区别

    C标准和C++标准在main函数上是有区别的,所以我分别详细来介绍他们. 对于C语言: C89标准的main()函数是可接受的,尽管现在建议是使用C99的标准.C99标准只定义了如下两种可接受的函数原 ...

  9. c语言 方程改main的值_c语言main函数里的参数argv和argc解析

    前言 一般我们平时写main函数的话,一般都是写不带参数的比较多,而且也习惯了这样写:其实标准的形式写法,main函数是带两个参数的,这两个参数分别是:argc和argv,那么这两个参数是表示什么意思 ...

最新文章

  1. c语言socket实现ftp,C++ socket实现miniFTP
  2. (0059)iOS开发之添加自定义字体库并设置文本字体
  3. 服务器系统都是64位的吗,云服务器32位跟64位的区别吗
  4. LeetCode 468 validate ip address(正则表达式)
  5. windows2008的功能介紹及其与2003的差异
  6. Entity Framework Core 使用HiLo生成主键
  7. java包 类 方法_Java中包与包之间方法的调用及其关键字区分(基础)
  8. 传输层与数据链路层滑动窗口协议的异同
  9. BCGControlBar MFC对话框换肤 续
  10. 注意,Fastjson 最新高危漏洞来袭!
  11. 二叉树的非递归遍历(转载)
  12. 常用圆圈数字序号(1~50)
  13. R-CNN解读+代码梳理
  14. 小米笔记本Air13.3加装固态硬盘
  15. 斯坦福大学公开课:量子力学
  16. 安全专业委员会发言_安全专业委员会发言稿
  17. 又一个吊打百度网盘的开源神器,还是99年妹子开发的
  18. win10 自动同步时间脚本
  19. gzdeflate函数_gzdeflate函数
  20. Thunderbolt4,雷电4与USB4

热门文章

  1. 2008年世界顶级杀毒软件排名
  2. 使用IDEA远程debug调试(一篇懂所有)
  3. ionic环境配置,生成apk
  4. 使用PHP进行网页爬取
  5. vim之vim忽略大小写查找字符串
  6. 猎豹移动Q3季报图解:游戏营收近3亿 成增长亮点
  7. 2G、3G、4G网络制式上下行频率、速率比较
  8. LTE 下行SINR测量
  9. 2022-2028年中国IC封测行业市场全景调查及投资前景分析报告
  10. day27旅游线路查询线路详情