推荐:《iPhone/Mac Objective-C内存管理教程和原理剖析》
http://www.cnblogs.com/VinceYuan/archive/2010/03/08/1680488.html
-(void) setObjB:(ClassB*) value
{
if (objB != value)
{
[objB release]; //原来的对象会先release
objB = [value retain]; //copy类似
}
}
assign针对简单数据类型(scalar types) ,如int,float, CGRect, NSInteger等,它只是简单的赋值操作
参考:《浅析ObjectiveC 深浅拷贝学习 》http://www.cocoachina.com/bbs/read.php?tid=80463
参考:《Presentation: Finding & Fixing Mem Leaks》
http://www.streamingcolour.com/blog/2010/09/21/presentation-finding-fixing-mem-leaks/
常见情况1:
// @property (nonatomic, retain) MyClass* objA;
- (void)foo{
//retainCount = 2
self.objA = [[MyClass alloc] init];
}
- (void)dealloc{
//retainCount = 1
[objA release];
[super dealloc];
}
修复方法:
// @property (nonatomic, retain) MyClass* objA;
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
- (void)foo{
//retainCount = 1
MyClass *obj = [[MyClass alloc] init];
//retainCount = 2
self.objA = obj;
//retainCount = 1
[obj release]
}
- (void)dealloc{
//retainCount = 0
[objA release];
[super dealloc];
}
常见情况2:
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
// @property (nonatomic, retain) MyClass* objA;
- (void)foo{
MyClass *obj = [[MyClass alloc] init];
self.objA = obj;
[obj release];
//retainCount = 1
}
- (void)dealloc{
//retainCount = 1
[super dealloc];
}
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
修复方法:
// @property (nonatomic, retain) MyClass* objA;
- (void)foo{
MyClass *obj = [[MyClass alloc] init];
self.objA = obj;
[obj release];
//retainCount = 1
}
- (void)dealloc{
//retainCount = 0
[objA release];
[super dealloc];
}
@property (retain) classA *abc;
@synthesize abc = _abc;
需要明白 self.abc 的默认实现,它相当于:
[_abc release];
_abc = nil;
前者会发送release消息,而后者可能有内存泄露。
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
简化了编程(本周上和MRR是一样的),不需要/不能使用下面这些方法
简单赋值,不会影响两边对象的retain count.
id my_id;
CFStringRef my_cfref;
NSString *a = (__bridge NSString*)my_cfref;
CFStringRef b = (__bridge CFStringRef)my_id;
-(void)test
{
CFStringRef coreFoundationString = CFStringCreateWithCString(CFAllocatorGetDefault(),"C String", kCFStringEncodingUTF8); // 创建 retainCount = 1
id unknownObjectType = (__bridge id)coreFoundationString; // 简单赋值,不变,retainCount = 1
CFStringRef anotherString = (__bridge_retained CFStringRef)unknownObjectType; // 保留赋值,加一,retainCount = 2
NSString *objCString = (__bridge_transfer NSString *)coreFoundationString; // 释放赋值,减一,retainCount =1;由于NSString*默认strong,加一,retainCount = 2
NSLog(@"String = %@", objCString);
objCString = nil; // 不再指向原内存,原内存减一,retainCount = 1
CFRelease(anotherString); // 释放,减一,retainCount = 0
}
#if __has_feature(objc_arc)
# define objc_retainedObject(o) ((__bridge_transfer id)(objc_objectptr_t)(o))
# define objc_unretainedObject(o) ((__bridge id)(objc_objectptr_t)(o))
# define objc_unretainedPointer(o) ((__bridge objc_objectptr_t)(id)(o))
#else
# define objc_retainedObject(o) ((id)(objc_objectptr_t)(o))
# define objc_unretainedObject(o) ((id)(objc_objectptr_t)(o))
# define objc_unretainedPointer(o) ((objc_objectptr_t)(id)(o))
#endif
@interface ClassA {
//NSObject _objB; // instance varible or ivar,可以不写,编译器会自动生成
}
@property (retain) NSObject *objB;
@end
@implement ClassA
@synthesize objB = _objB;
@end
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
@synthesize myProperty = myIvar; // a dynamic ivar named myIvar will be generated
@synthesize anotherProperty; // a dynamic ivar named anotherProperty will be generated
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->