首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

iPhone开发过程的迷惑

2012-09-06 
iPhone开发过程的困惑?? ?在学习苹果公司的iPhone SDK过程中碰过太多的问题了,由于缺乏名师指导,很多磕磕

iPhone开发过程的困惑

?? ?在学习苹果公司的iPhone SDK过程中碰过太多的问题了,由于缺乏名师指导,很多磕磕碰碰,也难免有不少牢骚,开一个帖子记录吧.对SDK的总结:

1 开发工具和技术的封闭性给很多初学者造成太多障碍,特别是集成了IB,用户对IB的工作机制不甚了解,造成很多问题.

2 关于什么地方retain,什么地方release,我现在还不是掌握的很好.

//***************************************************

自动创建按钮,一开始我是这样的

?

UIButton *btnNormal = [[UIButton buttonWithType:UIButtonTypeRoundedRect] initWithFrame:CGRectMake(0, 0, 40, 20)];[btnNormal addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];[btnNormal setTitle:@"Normal" forState:UIControlStateNormal];[btnNormal setFont:[UIFont systemFontOfSize:8]];[titleView addSubview:btnNormal];

?

?可是发现里面的文字(Title)死活出不来,一开始以为是字体大小/颜色/对齐有问题,试了很久,最终发现是该死的initWithFrame,非圆角按钮都可以按上述用法,圆角按钮则必须这样用:

?

UIButton *btnNormal = [UIButton buttonWithType:UIButtonTypeRoundedRect];[btnNormal setFrame:CGRectMake(0, 0, 40, 20)];

?你会知道苹果公司的代码是多么无厘头了吧.

//***************************************************

关于release的问题,这个问题远没有教科书上写的那么简单,一搬我们认为,如果一个对象被其他对象引用(赋值)了一次,就会retain一次,比如

?

UILable *lbl=[[UILable alloc] initWithFrame:...]];...[contentView addSubview:lbl];[lbl release];

?上面的方法是对的,lbl被引用到view中,可以release了,可是你把UILable换成UIButton试一试,release就会出错.我才或者跟组件继承的父类或者轻量级别有关,不过苹果公司显然是在扇自己一个巴掌.

还有在使用NSURLConnection时,NSURL和NSURLConnection不能release,否则会导致访问错误或者无限等待.

实际上,困难在于不是我不想或者忘记release,而是不知道是否应该release,或者这需要较长时间的经验

上面的几个代码都有点类似,实际上是OC几个不太规范的类,类似与button和image,都是不需要alloc和release的。 --shappy

//***************************************************

关于上面的release,总结出几个情况(这几个代码都是错误的)

?

NSString *userID=app.userID....[userID release];

?这种情况下release是会报错的,这种指针的赋值不需要release

?

NSArray *json = [jsonString JSONValue];....[json release];

?jsonFramework中的json对象同样不能release,似乎是个autorelease?

?

Font *font=[UIFont systemFnotOfSize:18];xxx[font release];

?又一次我用了上面的代码,结果被反复调用几次后就会报错,估计也是autorelease的对象,对于非显示alloc的对象,一搬是不需要释放的。类似 UIImage *img = [UIImage imageNamed:@"xxx"],这个据说是autorelease的,而且iPhone只支持这种读取图片文件的方式,这意味着只能由AutoreleasePool自己释放,在频繁读取大图片的时候,很容易造成崩溃。

没有alloc就不需要release,按照这个原则就ok了

//***************************************************

关于NSMutableArray的release问题,测试结果如下:

?

- (void)viewDidLoad {NSLog(@"view2 load");NSLog(@"retaincount:%d",[myData retainCount]);myData = [[NSMutableArray alloc] init];NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"Name1",@"title",@"New Name",@"subtitle",nil];    [myData addObject:dict];    [dict release];    dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"Name2",@"title",@"New Name",@"subtitle",nil];    [myData addObject:dict];    [dict release]; NSLog(@"retaincount:%d",[myData retainCount]);    [super viewDidLoad];}

?即使我在头文件中写了@property (nonatomic, retain) NSMutableData *myData;,第一次retiancount还是0,alloc后才设置为1,而注意到dict,是必须release的。看看delloca

?

- (void)dealloc {NSLog(@"view2 dealloc");NSLog([[myData objectAtIndex:0] valueForKey:@"title"]);NSLog([[myData objectAtIndex:1] valueForKey:@"title"]);[myData release];NSLog(@"retaincount:%d",[myData retainCount]);    [super dealloc];}

?结果如下:

?

2010-05-28 15:01:44.209 HelloWorld[1770:207] view2 dealloc

2010-05-28 15:01:44.210 HelloWorld[1770:207] Name1

2010-05-28 15:01:44.211 HelloWorld[1770:207] Name2

2010-05-28 15:01:44.211 HelloWorld[1770:207] retaincount:1

注意到release前后retaincount都是1,估计是不会太快释放的原因吧。

1 dealloc中可以 removeAllObjects,但是retainCount还是不会减少

2 如果把数组中的object在release,会报告“double free”的错误,估计删除时候会自动卸载。

?

?

?

1 楼 daisi2008 2012-03-21   引用可以release了,可是你把UILable换成UIButton试一试,release就会出错.我才或者跟组件继承的父类或者轻量级别有关,不过苹果公司显然是在扇自己一个巴掌.
如果是alloc方式创建的button可以释放,如果是通过类方法获取的不需要,cocoa内存管理原则认为其计数器为1且设置为自动释放了。如果是类方法获取的对象区分强弱引用,如果是全局的弱引用则需要手动的retain一下 保证不会被AutoreleasePool回收。
引用
类似 UIImage *img = [UIImage imageNamed:@"xxx"],这个据说是autorelease的,而且iPhone只支持这种读取图片文件的方式,这意味着只能由AutoreleasePool自己释放,在频繁读取大图片的时候,很容易造成崩溃.
这个你可以通过 [UIImage imageWithContentsOfFile:path];用NSBundle绑定路径加载图片,不用使用imageNamed:的application bundle获取图片内存里缓存。

其实内存只要注意 retain和release对应就好了

热点排行