Я знаю, что это ОЧЕНЬ поздно, но я думал, что смогу помочь людям, застрявшим в этом (как я).
performSelector:withObject:afterDelay
, кажется, работает нормально (другие ответы просто не будут работать по какой-то странной причине):
- (void)textViewDidBeginEditing:(UITextView *)inView
{
[self performSelector:@selector(setCursorToBeginning:) withObject:inView afterDelay:0.01];
}
- (void)setCursorToBeginning:(UITextView *)inView
{
//you can change first parameter in NSMakeRange to wherever you want the cursor to move
inView.selectedRange = NSMakeRange(3, 0);
}
источник: http://puppenspieler.tumblr.com/ запись / 757819650 / компл-selectedrange-в-UITextView
Вы можете поставить за ним точку с запятой, чтобы он выглядел и действовал больше как функция. Тогда он также правильно работает с предложениями if / else.
Без while (0) ваш приведенный выше код не будет работать с
if (doit)
INIT_LIST_HEAD(x);
else
displayError(x);
, поскольку точка с запятой после макроса "съест" предложение else, а приведенное выше не будет ' t даже компилировать.
Он позволяет сгруппировать несколько операторов в один макрос.
Предположим, вы сделали что-то вроде:
if (foo)
INIT_LIST_HEAD(bar);
Если макрос был определен без инкапсуляции do {...} while (0 );, приведенный выше код расширится до
if (foo)
(bar)->next = (bar);
(bar)->prev = (bar);
. Это явно не то, что было задумано, так как только первый оператор будет выполнен, если foo выполняется. Второй оператор будет выполняться независимо от того, выполняется ли foo.
Edit: Дальнейшее объяснение на http://c-faq.com/cpp/multistmt.html и http: // developer .apple.com / documentation / DeveloperTools / gcc-4.0.1 / cpp / Swallowing-the-Semicolon.html # Swallowing-the-Semicolon