как я могу динамически создать селектор во время выполнения с objective-c?

<p>я знаю, как создать <code>sel</code> во время компиляции, используя <code>@selector(mymethodname:)</code>, но я хочу создать динамический селектор из <code>nsstring</code>. это вообще возможно?</p><p>что я могу сделать:</p><pre><code>sel selector = @selector(dowork:); [myobj respondstoselector:selector]; </code></pre><p>что я хочу сделать: (псевдокод, это, очевидно, не работает)</p><pre><code>sel selector = selectorfromstring(@"dowork"); [myobj respondstoselector:selector]; </code></pre><p>я искал документы по apiapple, но не нашел способа, который бы не опирался на синтаксис <code>@selector(mytarget:)</code> во время компиляции.</p>

<p>я не программист objective-c, просто сочувствующий, но, возможно, <a href="https://developer.apple.com/documentation/foundation/1395294-nsselectorfromstring?language=objc">nsselectorfromstring</a> - это то, что вам нужно. в <a href="http://developer.apple.com/documentation/cocoa/conceptual/objectivec/articles/chapter\_9\_section\_3.html">runtime reference</a> упоминается о простоте, которую вы можете использовать для преобразования строки в селектор.</p>

<p>согласно документации xcode, ваш psuedocode в основном понимает это правильно.</p><blockquote> <p>наиболее эффективно присваивать значения переменным sel во время компиляции с помощью директивы @selector (). однако в некоторых случаях программе может потребоваться преобразовать строку символов в селектор во время выполнения. это можно сделать с помощью функции nsselectorfromstring:</p> </blockquote><p><code>setwidthheight = nsselectorfromstring(abuffer);</code></p><p>правка: облом, слишком медленно. :п</p>

<p>я бы сказал, что <em> это немного сложнее </em>, чем могли бы предположить ответы предыдущих респондентов ... если вы действительно этого хотите <strong> создать селектор </strong> ... а не просто "позвонить одному", который у вас "лежит" ...</p><p>вам нужно создать указатель на функцию, который будет вызываться вашим "новым" методом .. поэтому для такого метода, как <code>[self themethod:(id)methodarg];</code>, вы должны написать ...</p><pre><code>void (^impblock)(id,id) = ^(id \_self, id methodarg) { [\_self dosomethingwith:methodarg]; }; </code></pre><p>и затем вам нужно динамически сгенерировать блок <code>imp</code>, на этот раз, передавая "self", <code>sel</code> и любые аргументы ...</p><pre><code>void(*impfunct)(id, sel, id) = (void*) imp\_implementationwithblock(impblock); </code></pre><p>и добавьте его в свой класс вместе с точной сигнатурой метода для всей присоски (в данном случае <code>"v@:@"</code>, возврат void, вызывающий объект, аргумент объекта)</p><pre><code> class\_addmethod(self.class, @selector(themethod:), (imp)impfunct, "v@:@"); </code></pre><p>вы можете увидеть несколько хороших примеров такого рода <a href="https://github.com/mralexgray/atozautobox"><em> shenanigans во время выполнения </em>, в одном из моих репозиториев, здесь.</a> </p>

<p>я знаю, что на это уже давно дан ответ, но все же хочу поделиться. это также можно сделать с помощью <code>sel\_registername</code>.</p><p>пример кода в вопросе можно переписать так:</p><pre><code>sel selector = sel\_registername("dowork:"); [myobj respondstoselector:selector]; </code></pre>