如何避免循环引用造成的内存泄漏呢:
以delegate模式为例(viewcontroller和view之间就是代理模式,viewcontroller有view的使用权,viewcontroller同时也是view的代理(处理view中的事件)):- UserWebService.h
- #import
- //定义一个ws完成的delegate
- @protocol WsCompleteDelegate
- @required
- -(void) finished;//需要实现的方法
- @end
- @interface UserWebService:NSObject
- {
- id delegate;//一个id类型的dategate对象
- }
- @property (assign) id delegate;
- -(id)initWithUserData:(User *)user;
- -(void)connectionDidFinishLoading:(NSURLConnection *)connection;
- @end
- UserWebService.m:
- #import
- @systhesize delegate;//同步这个delegate对象
- @implementation UserWebService
- -(void)connectionDidFinishLoading:(NSURLConnection *)connection
- {
- [delegate finished]
- }
- @end
- #import "UserWebService.h" //包含含有委托的头文件
- @interface LoginViewController:UIViewController
- -(void)submit;
- @end
- LoginViewController.m:
- @implementation LoginViewController
- -(void) submit
- {
- User *user = [[User alloc]init];
- [user setUserId:@"username"];
- [user setPassword:@"password"];
- ws = [[UserWebService alloc] initWithUserData:user];
- ws.delegate = self;//设置委托的收听对象
- [user release];
- [ws send];
- }
- //实现委托中的方法,
- -(void) finished
- {
- NSAttry *users = [ws users];
- }
- @end
- @property (assign) id delegate;
- LoginViewController alloc了一个UserWebService,UserWebService的代理又是LoginViewController,这样就循环引用了:
- ws = [[UserWebService alloc] initWithUserData:user]; //UserWebService对象引用计数加1
- ws.delegate = self;//LoginViewController对象引用计数加1
- ClassA *a = [[ClassA alloc] init];
- ClassA *a = [[ClassA alloc] init];
- ClassA *b = a;//a和b指向的对象的引用计数还是1
:
默认为@property为@property(atomic,assign) nonatomic: 没有对应的atomic关键字,即使上面是这么写,但atomic叧是在你没有声明这个特性的时候系统默认,你无法主动去声明这一特性。nonatomic不支持多线程访问,atomic有同步机制,支持多线程访问,如果需要多线程访问,声明为atomic(维持默认),否则声明为nonatomic,因为nonatomic效率比atomic高得多 关于assign、retain和copy: assign是系统默认的属性特性,它几乎适用亍OC的所有变量类型。对于非对象类型的变量,assign是唯一可选的特性。但是如果你在引用计数下给一个对象类型的变量声明为assign,那么你会在编译的时候收到一条来自编译器的警告。因为assign对于在引用计数下的对象特性,叧创建了一个弱引用(也就是平时说的浅复制)。返样使用变量会很危险。当你release了前一个对象的时候,被赋值的对象指针就成了无头指针了。因此在为对象类型的变量声明属性的时候,尽量少(或者不要)使用assign。 关于assign合成的setter,看起来是这样的:- -(void)setObjA:(ClassA *)a {
- objA = a;
- }
- -(void)setObjA:(ClassA *)a
- {
- If(objA != a)
- {
- [objA release];
- objA = a;
- [objA retain]; //对象的retain count 加1
- }
- }
- NSString *str = [[NSString alloc] initwithstring @“abc”];
- str = @“abcd”;‘
- [str release];
- NSLog("%@",str);//打印出abcd