<iOS>关于子线程和block中操作主线程界面的控件讨论
2013-04-06 22:02
555 查看
在viewDidLoad中写入如下代码:
- (void)viewDidLoad
{
[super
viewDidLoad];
showLabel = [[UILabel
alloc] initWithFrame:CGRectMake(10,
10,
300, 40)];
[self.view
addSubview:showLabel];
NSInteger (^myBlock)(NSInteger) = ^(NSInteger age) {
showLabel.text = [NSString
stringWithFormat:@"ange=%d", age];
NSLog(@"your age is %d", age);
return age*2;
};
NSLog(@"block called. result=%d", myBlock(32));
UIButton *btn = [UIButton
buttonWithType:UIButtonTypeRoundedRect];
btn.frame =
CGRectMake(10,
100, 300,
40);
[self.view
addSubview:btn];
[btn addTarget:self
action:@selector(btnClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
运行, 我们会发现因为myBlock(32)被调用, 主界面上的showLabel被设置,由此可见block中是可以直接设置主界面的控件。
接着看btnClicked:方法
- (void)btnClicked:(id)sender {
NSThread *aThread = [[NSThread
alloc] initWithTarget:self
selector:@selector(newThread:)
object:nil];
[aThread
start];
[aThread
release];
}
- (void)newThread:(id)sender {
NSLog(@"nbew Thread, This is in new thread");
showLabel.text = [NSString
stringWithFormat:@"Hello, from butn."];
}
运行,我们发现, 点按钮后,线程运行,并且showLabel的text被设置成"hello. from buton."由此可见,在子线程中是可以直接设置主界面上的控件的。
然后我们再看一个重力加速度的代码,
self.motionManager = [[[CMMotionManager
alloc] init]
autorelease];
NSOperationQueue *queue = [[[NSOperationQueue
alloc]
init] autorelease];
motionManager.accelerometerUpdateInterval =
1.0/30.0;
[motionManager
startAccelerometerUpdatesToQueue:queue
withHandler:
^(CMAccelerometerData *accelerometerData,
NSError *error) {
// 这里可以尝试进行
showLabel.text =
[NSString stringWithFormat:@"from
accelerometer."];
}];
运行后,我们发现根本不能影响到主线程的控件,不知何故,估计是因为这个block和上面直接生成的 block有所不同,所以前面的block是可以设置,而在这里的accelerometer的handler中是不可设置的。
当然上面的演示,并不表示我们就应该用子线程或者block来操作主界面的控件,仅仅是一个讨论而已, 正常的情况还是应该使用下面的方式来修改主线程UI的控件。
[self performSelectorOnMainThread:@selector(updateMainUI:) withObject:nil waitUntilDone:NO];
- (void)viewDidLoad
{
[super
viewDidLoad];
showLabel = [[UILabel
alloc] initWithFrame:CGRectMake(10,
10,
300, 40)];
[self.view
addSubview:showLabel];
NSInteger (^myBlock)(NSInteger) = ^(NSInteger age) {
showLabel.text = [NSString
stringWithFormat:@"ange=%d", age];
NSLog(@"your age is %d", age);
return age*2;
};
NSLog(@"block called. result=%d", myBlock(32));
UIButton *btn = [UIButton
buttonWithType:UIButtonTypeRoundedRect];
btn.frame =
CGRectMake(10,
100, 300,
40);
[self.view
addSubview:btn];
[btn addTarget:self
action:@selector(btnClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
运行, 我们会发现因为myBlock(32)被调用, 主界面上的showLabel被设置,由此可见block中是可以直接设置主界面的控件。
接着看btnClicked:方法
- (void)btnClicked:(id)sender {
NSThread *aThread = [[NSThread
alloc] initWithTarget:self
selector:@selector(newThread:)
object:nil];
[aThread
start];
[aThread
release];
}
- (void)newThread:(id)sender {
NSLog(@"nbew Thread, This is in new thread");
showLabel.text = [NSString
stringWithFormat:@"Hello, from butn."];
}
运行,我们发现, 点按钮后,线程运行,并且showLabel的text被设置成"hello. from buton."由此可见,在子线程中是可以直接设置主界面上的控件的。
然后我们再看一个重力加速度的代码,
self.motionManager = [[[CMMotionManager
alloc] init]
autorelease];
NSOperationQueue *queue = [[[NSOperationQueue
alloc]
init] autorelease];
motionManager.accelerometerUpdateInterval =
1.0/30.0;
[motionManager
startAccelerometerUpdatesToQueue:queue
withHandler:
^(CMAccelerometerData *accelerometerData,
NSError *error) {
// 这里可以尝试进行
showLabel.text =
[NSString stringWithFormat:@"from
accelerometer."];
}];
运行后,我们发现根本不能影响到主线程的控件,不知何故,估计是因为这个block和上面直接生成的 block有所不同,所以前面的block是可以设置,而在这里的accelerometer的handler中是不可设置的。
当然上面的演示,并不表示我们就应该用子线程或者block来操作主界面的控件,仅仅是一个讨论而已, 正常的情况还是应该使用下面的方式来修改主线程UI的控件。
[self performSelectorOnMainThread:@selector(updateMainUI:) withObject:nil waitUntilDone:NO];
相关文章推荐
- <iOS>关于Xcode上的Other linker flags
- <iOS>关于Xcode上的Other linker flags
- 关于<< 和>>操作
- <iOS>关于Xcode上的Other linker flags
- <iOS开发兼容问题>关于IOS6和IOS5旋屏问题
- <蓝牙BLE>关于cc2540Flash断电保存的操作
- <iOS>关于Xcode上的Other linker flags
- <iOS>关于自定义description的一点用法
- <iOS>关于viewWithTag的一点说明
- <iOS>关于Xcode上的Other linker flags
- <iOS>关于viewWithTag的一点说明
- <iOS开发兼容问题>关于IOS6和IOS5旋屏问题
- <iOS>关于Xcode上的Other linker flags
- &lt;转&gt;iOS的socket开发基础
- <s:iterator>使用status获取当前遍历数据的行数、序号等操作
- <asp:Menu> 控件 应用css样式
- <Android>界面美化的一点点积累
- <iOS>NSXMLParser具体解析xml的应用详解
- iOS 学会使用delegate和block<一>
- <总结>delphi WebBrowser控件的使用中出现的bug