Как заблокировать выполнение кода в приложении iOS

описание проблемы

У меня есть функция StdString ShowLockScreen() в этой функции я называю activateViewController функция, которая показывает некоторый пользовательский интерфейс, где пользователь должен ввести PIN-код, сразу после вызова activateViewController Функция Я хочу заблокировать все процессы до тех пор, пока пользователь не введет свой PIN-код и не нажмет кнопку ОК на открытом интерфейсе. Ниже вы можете увидеть код, который я пытаюсь

Исходный код в 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]; из моего пользовательского интерфейса и код будет продолжать выполняться. Но это не работает в моем случае.

Исходный код в 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];

но как использовать это в моем коде?

0

Решение

Ответ на проблему

Вы можете заблокировать темы, используя NSLock, но в вашей ситуации это не похоже на применение. Причина в том, что блокировка в основном используется для обеспечения безопасности потоков при доступе к данным из нескольких потоков. Вы запрашиваете блокировку на уровне домена, которая не позволяет пользователю использовать приложение, если они не ввели свой PIN-код. Эти две концепции имеют одно и то же слово «блокировка», но в своей реализации они совершенно разные. Если бы вы были использовать NSLock и связанные с ним аналоги, вы просто вынуждаете свою реализацию в отдельные потоки, чтобы блокировать взаимодействие с пользователем, и рискуете усложнить ваш проект и избежать проблем при отладке (много тупиков?).

Предлагаемое решение

Поскольку концепция представляет собой механизм блокировки на уровне домена, я предлагаю сохранить его таким образом для его реализации. Если вы хотите, чтобы он был аналогичен Android, вам нужно будет создать собственную концепцию SharedObject, которую запрашивает все остальное. Если этот объект скажет: «Пользователь не разблокировал приложение», то ничего не будет обрабатываться. Это избавляет вас от ручного управления потоками и освобождает потоки до того момента, когда они вам действительно нужны (например, асинхронная обработка).

Чтобы реализовать этот объект, давайте назовем его UserContext, который доступен как синглтон. Как реализовать этот sharedInstance можно увидеть здесь.

Если у вас есть это, вы можете добавить к нему различные свойства, которые являются глобальными для всего приложения (и, по предложению имени, имеют все глобальные свойства, которые принадлежат конкретному пользователю). Одним из этих свойств является то, заблокировано ли приложение у пользователя:

[[UserContext sharedInstance] isLocked] // Returns BOOL

Используя это в своем приложении, вы можете контролировать (на уровне концепции домена), может ли метод что-то вычислять или нет (естественно, вам нужно UserContext потокобезопасен, так как он может быть запрошен в любом месте в любое время). Разработчику, читающему код, будет ясно, что определенный метод не может ничего сделать, если пользователь не разблокировал приложение. Прекратить

Примечания стороны

Я хочу, чтобы мой код остановился, тогда я звоню [theLock lock]; и после я позвоню [theLock unlock]; из моего пользовательского интерфейса и код будет продолжать выполняться.

Ни при каких обстоятельствах не блокируйте поток пользовательского интерфейса. В опубликованном приложении сторожевой таймер убьет ваше приложение и, по сути, вылетит.

1

Другие решения

ViTo, насколько я беспокоился о NSLock, мы используем его в случае многопоточности, в которой мы блокируем определенный поток и заставляем его, чтобы он не разблокировался, ни один другой поток не становился активным или выполнял свою требуемую задачу.
Итак, может быть, мы можем сделать это, прежде всего, мы запустим все ваши процессы с точки зрения потока и в тот момент, когда вы пытаетесь открыть свой пользовательский интерфейс, мы называем «блокировка» и когда пользователь нажимает кнопку после ввода текста, затем мы называем «разблокировать».
Но для этого мы должны быть уверены, что этот поток имеет высокий приоритет.
Это то, о чем я думаю сейчас, но действительно попробуй это с моим примером кода и обновлю тебя соответственно.

Проверьте эту часть кода:

+(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];
}

Проверьте журнал, вы получите то, что вы хотите.
Надеюсь, это то, что вам нужно. За всякое беспокойство, кричите на меня.

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]!!!")
}
0