ios arc 经验总结

   关于arc,自动内存管理机制,现总结一下几点:

1.ios 配置方法:直接在targets->build phases中修改compiler Flags,是否支持arc。添加:-fobjc-arc,就可以让旧项目支持arc。如果想让原来支持arc的不使用arc则添加-fno-objc-arc


2.如果使用了arc,在你的代码中 不可以使用retain, release, autorelease,如果使用的话会报错。
3. 如果使用了arc,在@property声明中,用strong代替retain。在支持__unsafe_unretained的情况下,__unsafe_unretained相当于assign。
4.如果使用了arc,NSAutoReleasePool也不能使用,测试发现,用@autoreleasepool 代替,不会编译报错。
5.不管在不在arc下,object对象都有强引用、弱引用之分,当需要保持(拥有)其他对象的时候,需要retain。
6.在arc中,使用strong、weak修饰的变量,当对象不再存在的时候会被置为nil。而[align=-webkit-left]__unsafe_unretained不会被置为nil,会成为野指针,是不安全的,再次访问可能造成错误。[align=-webkit-left]3,引用关键字:arc中,变量声明默认为_strong.

7.在build phases 中改变了arc 后,代码里也要进行判断,是否支持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([[NSArrayalloc]init]);
 //如果支持arctestArray就只是alloc init,release的事情由系统来做。

//如果不支持arc,那这条语句相当于:
NSArray *testArray = [[[NSArray alloc] init] autorelease];



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

8.在delloc 中需要这样做
类如果注册了通知(观察者模式),需要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
}
9.
property 的修饰符总结如下:
  1. strong:等同于"retain",属性成为对象的拥有者
  2. weak:属性是 weak pointer,当对象释放时会自动设置为 nil,记住 Outlet应该使用 Weak
  3. unsafe_unretained:等同于之前的"assign",只有 iOS 4 才应该使用
  4. copy:和之前的 copy 一样,复制一个对象并创建 strong 关联
  5. assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然可以使用
  6. delegate 用weak

10. 转化的另一种方式为:Xcode 的 ARC 自动转换工具:Edit\Refactor\Convert to Objective-C ARC
勾选需要转的,不勾选的默认不用转化,这是另一种更方便的方法。
11.对于readonly 的转化
未使用arc
@property (nonatomic, readonly) NSString *result;
使用后
@property (nonatomic, strong, readonly) NSString *result;
若有时候你需要修改,你可以这么用
.h文件

interface WeatherPredictor ()

@property (nonatomic, strong, readonly) NSNumber *temperature;

@end



.m文件中再次申明私有

interface WeatherPredictor ()

@property (nonatomic, strong, readwrite) NSNumber *temperature;

@end

12.关于AutoreleasePool 的写法
arc 使用前

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

int retVal = UIApplicationMain(argc, argv, nil,

NSStringFromClass([AppDelegate class]));

[pool release];
return retVal;

arc 使用后
会修改变:

 
 
@autoreleasepool {

int retVal = UIApplicationMain(argc, argv, nil,

NSStringFromClass([AppDelegate class]));

return retVal;
 }

若是创建一个object 最后将object 写在autoreleasepool 外面

13.关于delloc ,不能再调用【super delloc】,一般除非是一些非release 如消息的removeobject ,否则可不用调用delloc,当然,CFString 的release 还是必要的。

14.关于属性,用了arc 后,一般来说,仅仅为了简化内存管理,是不再需要使用 property 的,虽然你仍然可以这样做,但直接使用实例变量是更好的选择。只有那些属于public 接口的实例变量,才应该定义为 property。我们只需在。m类中定义priviate 实例就好。使用时仍然可以用setter 和getter 迭代器。

15.关于快语句。如switch

在没用arc前

switch(x)

{

case Y:

NSString *S=……;

break;

}

但是使用arc后上面的语句会报错

必须将case后的语句用括号括起来

如:

switch(x)

{

case Y:

{

NSString *S=……;

break;

}

}

这样arc 才能确定变量的作用域,从而适当的时候释放该变量。


16.关于Toll-Free Bridging的转化

使用arc 前

- (NSString *)escape:(NSString *)text
{

return [(NSString *)CFURLCreateStringByAddingPercentEscapes(

NULL,

(CFStringRef)text,

NULL,

(CFStringRef)@"!*'();:@&=+$,/?%#[]", // 这里不需要 bridging

casts,因为这是一个常量,不需要释放!

CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncodin

g))

autorelease];

}

使用arc 后

- (NSString *)escape:(NSString *)text

{

return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(

NULL,

(__bridge CFStringRef)text,

NULL,

CFSTR("!*'();:@&=+$,/?%#[]"),

CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncodin

g)))


}

  • 使用 CFBridgingRelease(),从 Core Foundation 传递所有权给Objective-C;

  • 使用 CFBridgingRetain(),从 Objective-C 传递所有权给 CoreFoundation;

  • 使用__brideg,表示临时使用某种类型,不改变对象的所有权。


你可能感兴趣的:(ios,基础,object-c)