您的位置:首页 > 移动开发 > IOS开发

<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];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: