ios - 如何阻止代码等待连接
<p><p>我一直在为一些 sensorTag 提供新的 API。我需要等待连接解决,否则我的代码将在第一次运行时失败。我有以下代码片段:</p>
<pre><code>- (void)viewDidLoad {
;
self.sensorGyro = ;
if(self.sensorGyro){
while (!self.sensorGyro.client.isDeviceConnected) {
NSLog(@"Awaiting connection");
}//Check that connection has been made
NSLog(@"connection UP");
[self.sensorGyro.client.sensorManager startGyroUpdatesToQueue:nil errorRef:nil withHandler:^(MSBSensorGyroData *GyroData, NSError *error) {
NSLog(@"Starting updates");
self.currentGyroLabel.text = ;
}];
</code></pre>
<p>最初我没有 while 循环。我使用了 2-3 秒的 dispatch_after 调用。但是我觉得等待固定时间不好,最好是连接后继续。但是当我使用 while 循环时,我的应用程序会停止并停止工作。没有崩溃,只是停下来。谁能告诉我为什么会这样。因为我已经验证了连接只需要 2 秒,我没有看到执行 while 循环的问题?另外,有没有更好的方法来“等待”东西完成/变干。</p>
<p>提前致谢</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p><code>MSBSensorUV</code> 类正在启动一些异步连接过程。</p>
<ol>
<li><p>如果您要循环等待状态更改,您可以将其分派(dispatch)到后台线程(正如 Luke 隐晦地建议的那样)。这可以防止应用阻塞主线程。</p>
<p>问题是你仍然有一个线程被捆绑在一个浪费的练习中,不断地轮询以查看 <code>isDeviceConnected</code> 是否为真。这就像一个 child 在汽车后座上不断问“我们到了吗?”</p>
</li>
<li><p>更好的是,您可以采用事件驱动模式,例如使用 Matteo 建议的 KVO。这样,您将在 <code>isDeviceConnected</code> 属性更改时收到通知,而不是此代码不断轮询。</p>
<p>如果您遇到一个不提供完成 block 但会异步更改某些属性的类,这会更有效,并且是一种很好的方法。</p>
</li>
<li><p>最好,因为 <code>MSBSensorUV</code> 是您自己的类,您可以重构它以提供一个连接完整的处理程序 block 。这样,您就可以避免上述方法带来的复杂性。</p>
</li>
</ol>
<hr/>
<p>离线,您分享了一点 <code>MSBSensorUV</code> 实现:</p>
<pre><code>+ (MSBSensorUV *)createObjectUV{
static MSBSensorUV *UVObject;
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
UVObject = [init];
});
return UVObject;
}
- (MSBSensorUV *)init{
self = ;
if(self){
.delegate = self;
NSArray *clients = [ attachedClients];
self.client = ;
if(self.client == nil){
//no bands attached
return nil;
}
[ connectClient:self.client];
}
return self;
}
</code></pre>
<p>首先,<code>createObjectUV</code> 正在创建一个单例,因此您应该将其重命名为 <code>sharedSensor</code> 之类的名称(使用 <code>shared</code> 的前缀可以清楚地表明你正在处理一个单例):</p>
<pre><code>+ (instancetype)sharedSensor {
static MSBSensorUV *uvObject;
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
uvObject = [ init];
});
return uvObject;
}
</code></pre>
<p>其次,<code>init</code>不应启动连接。</p>
<pre><code>- (instancetype)init {
self = ;
if (self) {
.delegate = self;
NSArray *clients = [ attachedClients];
self.client = ;
if(self.client == nil){
//no bands attached
return nil;
}
// [ connectClient:self.client];
}
return self;
}
</code></pre>
<p>坦率地说,在单例的上下文中,如果没有附加带,则返回 <code>nil</code> 的概念可能没有意义(因为一旦将其设置为 <code>nil</code>,在您终止应用程序之前,您永远无法再次访问此单例)。所以你可能也想从 <code>init</code> 中提取这个逻辑,但我会让你自己解决这个问题。</p>
<p>第三,您将为连接完成处理程序声明一个属性:</p>
<pre><code>@property (nonatomic, copy) void (^connectionCompletionHandler)(BOOL success, NSError *);
</code></pre>
<p>第四,您将创建一个 <code>connectionWithCompletionHandler</code> 方法,例如:</p>
<pre><code>- (void)connectWithCompletionHandler:(void (^)(BOOL success, NSError *error))block
{
self.connectionCompletionHandler = block;
[ connectClient:self.client];
}
</code></pre>
<p>然后您的连接委托(delegate)方法将调用此完成处理程序,例如<code>clientDidConnect</code> 会调用:</p>
<pre><code>if (self.connectionCompletionHandler) {
self.connectionCompletionHandler(TRUE, nil);
self.connectionCompletionHandler = nil;
}
</code></pre>
<p>而<code>didFailToConnectWithError</code>会报失败:</p>
<pre><code>if (self.connectionCompletionHandler) {
self.connectionCompletionHandler(FALSE, error);
self.connectionCompletionHandler = nil;
}
</code></pre>
<p>最后,回到你的原始代码示例,它看起来像:</p>
<pre><code>- (void)viewDidLoad {
;
self.sensorGyro = ;
[self.sensorGyro connectWithCompletionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(@"connection UP");
[self.sensorGyro.client.sensorManager startGyroUpdatesToQueue:nil errorRef:nil withHandler:^(MSBSensorGyroData *GyroData, NSError *error) {
NSLog(@"Starting updates");
self.currentGyroLabel.text = ;
}];
} else {
NSLog(@"Error connecting: %@", error);
}
}];
}
</code></pre></p>
<p style="font-size: 20px;">关于ios - 如何阻止代码等待连接,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/29572544/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/29572544/
</a>
</p>
页:
[1]