降低耦合性
- (IBAction)doSomeThing:(id)sender
将参数的类型设置为id可以降低控制器与其控制的view(控件也属于view)之间的耦合性,因为这样在改变所使用的view时,控制器不需要作任何修改。
使用线程注意事项
慎用线程,能不开线程的地方尽量不开线程。如确实需要使用线程时,需要主要以下几点:
1.如果新线程执行的内容(selector)是由当前对象所提供,则完全可以使用 [self performSelectorInBackground:withObject:]代替[NSThread detachNewThreadSelector:toTarget:withObject:]。
2.新线程执行的内容(selector)中需要设置自动释放池,以避免内存泄漏。
-(void)someMethodExcutedByNewThread{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init];
...//新线程具体执行的内容。
[pool drain];
}
3.严格的说,在非主线程中修改View是不合理的。虽然大多数情况,非主线程中修改View中的内容并不会出问题,但你不能99.999%的安全。所以不推荐在非主线程中修改控件或View中的内容。
如果确实需要开线程做一些比较费时的操作并且在操作完后需要更新view,如从网站上下载图片并显示,正确的做法是在非主线程中执行下载图片的操作,然后执行[self performSelectorOnMainThread:withObject:waitUntilDone:],在主线程中更新view中的内容。用[self performSelectorOnMainThread:withObject:waitUntilDone:]更新view时还需注意一点,那就是需要检查你要修改的view到底存不存在。这是很有必要的,因为在执行新线程的过程中,需要修改的view很可能在主线中已经被释放并被清理了(如发生内存警告、已跳转到其他view)。
下面是如何使用线程的具体实例:
- (void)updateProgressView:(NSArray *)progressViewAndProgress{
UIProgressView *progressView = [progressViewAndProgress objectAtIndex:0];
NSNumber *progress = [progressViewAndProgress objectAtIndex:1];
//执行到这里时, progressView对象肯定还存在,不管self.view存不存在。所以不需要判断progressView是否已经完成被释放了
progressView.progress = [progress floatValue];
}
- (void)downloadPic:(UIProgressView *)progressView{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSNumber *progress;
NSArray *progressViewAndProgress;
for (int i = 0; i < 100; i++) {
progress = [NSNumber numberWithFloat: (i + 1.0) / 100];
progressViewAndProgress = [NSArray arrayWithObjects:progressView, progress, nil];
//progressView.progress = (i + 1.0) /100; 这样不行,非要在另外一个线程中更新才行
[self performSelectorOnMainThread:@selector(updateProgressView:)
withObject:progressViewAndProgress
waitUntilDone:YES];
[NSThread sleepForTimeInterval:0.5]; //模拟下载操作
}
[pool drain];
}
- (IBAction)dowloadPicAndUpdateProgressView:(id)sender{
UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
progressView.center = CGPointMake(300, 400);
progressView.bounds = CGRectMake(0, 0, 300, 10);
[self.view addSubview:progressView];
//可以使用[NSThread detachNewThreadSelector:@selecto(downloadPic:) toTarget:self withObject:progressView]代替
[self performSelectorInBackground:@selector(downloadPic:) withObject:progressView];
//这样做会卡住界面
//[self performSelectorOnMainThread:@selector(downloadPic:) withObject:progressView waitUntilDone:NO];
[progressView release];
}