0

问题描述

StdString ShowLockScreen()在这个函数中有一个函数我调用activateViewController函数显示一些用户必须输入 PIN 的 UI,就在调用activateViewController函数之后我想锁定所有进程,直到用户输入他的 PIN 并在打开的 UI 上按 OK 按钮。下面你可以看到我尝试的代码

iOS 中的源代码

StdString ShowLockScreen() 
{
    // Create a lock.
    NSLock* theLock = [[NSLock alloc] init];
    // Create a UI in which user must enter his PIN.
    PinLockController* controller = [[PinLockController alloc] initWithStyle:PinLockTypeSet];
    // Set delegate. 
    controller.delegate = m_Context;

    // !!! Here I show a UI and just after that I lock my lock in order code stop executing there.
    [controller activateViewController:nil];

    @synchronized(theLock) {
        [theLock lock];
    }

    NSLog(@"User in UI unlock the lock");
}

我希望我的代码停止然后我打电话[theLock lock];,然后我会打电话 [theLock unlock]; 从我的 UI 和代码将继续执行。但它在我的情况下不起作用。

Android中的源代码

我在 Android 中编写了类似的应用程序,这里是代码。我想在 iOS 中写同样的东西,但我找不到解决方案

Intent intent = new Intent(mCtx, SoftPinActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

SharedObject lock = new SharedObject("");
int lockId = SharedObject.acquireLockId(lock);
Logger.i(TAG, "lockId = " + lockId);
intent.putExtra(SharedObject.LOCK_ID, lockId);
intent.putExtra(SoftPinActivity.UI_ID, style);

synchronized (lock) {
   mCtx.startActivity(intent);
   try {
          Logger.i(TAG, "lock.wait()...");
          lock.wait();
   } catch (InterruptedException e) {
          e.printStackTrace();
          Logger.i(TAG, "InterruptedException");
   }
}
Logger.i(TAG, "lock.wait()...done");
SharedObject.releaseLockId(lockId);

String pin = lock.object();

研究

我想我必须使用

NSCondition* condLock = [[NSCondition alloc] init];
[condLock wait];

[condLock signal];

但是如何在我的代码中使用它?

4

3 回答 3

1

对问题的回答

您可以使用 锁定线程NSLock,但在您的情况下,这似乎不适用。原因是锁定主要用于在从多个线程访问数据时提供线程安全。您要求的是域级锁定,它可以防止用户使用该应用程序,除非他们输入了他们的 PIN。这两个概念共享“锁”这个词,但它们的实现方式完全不同。如果您要使用NSLock它及其相关的对应物,那么您将强制实现到单独的线程中,纯粹是为了阻止用户交互,并冒着使您的项目复杂化和调试麻烦(死锁很多?)的风险。

建议的解决方案

由于这个概念是一个域级别的锁定机制,我建议我们保持这种方式来实现它。如果您希望它类似于 Android,那么您需要创建自己的“SharedObject”概念,以供其他一切查询。如果此对象说“用户尚未解锁应用程序”,则不会进行任何处理。这使您远离手动管理线程,并在您真正需要它们时释放线程(例如异步处理)。

为了实现这个对象,我们称它为 a UserContext,它可以作为一个单例使用。如何实现这个 sharedInstance可以在这里看到

一旦你有了它,你就可以向它添加各种属性,这些属性在整个应用程序中都是全局的(并且根据名称的建议,具有属于特定用户的所有全局属性)。这些属性之一是用户是否锁定了应用程序:

[[UserContext sharedInstance] isLocked] // Returns BOOL

在整个应用程序中使用它,然后您可以控制(在域概念级别)方法是否可以计算某些东西(当然,您需要使UserContext线程安全,因为它可以在任何时间任何地方查询)。它会让阅读代码的开发人员清楚地知道,除非用户解锁了应用程序,否则某个方法不能做任何事情。停止

旁注

我希望我的代码停止然后我调用,然后我将从我的 UI 调用并且代码将继续执行[theLock lock];[theLock unlock];

在任何情况下都不要锁定 UI 线程。在已发布的应用程序中,看门狗会杀死您的应用程序,并且它实际上会崩溃。

于 2012-11-26T13:44:39.663 回答
0

ViTo,正如我所关心的 NSLock,我们在多线程的情况下使用它,在这种情况下,我们锁定一个特定的线程并强制它直到不解锁,没有其他线程变为活动或执行他所需的任务。因此,我们可以做的可能是首先我们以线程的形式启动所有进程,然后当您尝试打开 UI 时,我们称之为“锁定”,并且当用户在输入文本后按下按钮时 -框然后我们称之为“解锁”。但是,为此我们必须确保该线程具有高优先级。这就是我现在的想法,但真的用我的示例代码试试这个,并会相应地更新你。

检查那部分代码:

+(void)aMethod:(id)param{
 int x;
 for(x=0;x<50;++x)
 {enter code here
 [lock lock];
 printf("Object Thread says x is %i\n",x);
 usleep(1);
 [lock unlock];
 }
}

- (void)viewDidLoad
{    
 int x;
 lock = [[NSLock alloc] init];
 [NSThread detachNewThreadSelector:@selector(aMethod:) toTarget:[MViewController class] withObject:nil]; 
 for(x=0;x<50;++x)
 {
 [lock lock];
 printf("Main thread says x is %i\n",x);
 usleep(10000);
 printf("Main thread lets go %i\n",x);
[lock unlock];
 usleep(100);
 }
 printf("Now getting the process");
[super viewDidLoad];
}

检查日志你会得到你想要的。希望,这是你需要的。如有任何顾虑,请对我大喊大叫。

于 2012-11-26T12:21:06.200 回答
0

好的,我找到了解决这个问题的方法,下面你可以看到实现的功能和逐行描述。

StdString ShowLockScreen() 
{
    // Create NSCondition lock object.
    NSCondition* conditionLock = [[NSCondition alloc] init];

    // Here I create my UI which must ask user to enter PIN.
    PinLockController* controller = [[PinLockController alloc] initWithStyle:PinLockTypeSet];
    controller.delegate = m_Context;

    // Here I lock the thread but not main thread (this is very important) I start
    // ShowLockScreen function in new thread and lock it.
    [conditionLock lock];

    dispatch_sync(dispatch_get_main_queue(), ^{
        // I call function which shows my UI in main thread as UI can be shown 
        // only in MAIN THREAD. (This is important too.)
        [controller ShowLockController:conditionLock];
    });

    // Then I set lock to wait, how you can see I pass conditionLock as an 
    // argument to ShowLockController function in that function when user
    // enter his PIN and press okay button I call [conditionLock signal];
    // and my code code here after wait and continue executing.
    [conditionLock wait];

    NSLog(@"Come here then I call [conditionLock signal]!!!")
}
于 2012-11-27T08:19:06.060 回答