Je voudrais ajouter des fonctions en créant une catégorie pour les blocs de l'objectif-c. au lieu de simplement permettre à la normale catégorie possible p> [copie Ablock] code>,
[Ablock conserver] code>,
[version Ablock] code>,
[Ablock AutoRelease] code>. Je pourrais faire une chose comme: p>
5 Réponses :
La réponse simple est non. Une variable __block est un objet de niveau C et non un objet C objectif C. Vous pouvez appeler [copie ABLOCK], mais cela invoque une fonction de fonction C_copy () non la méthode de copie NsObject. Donc, le type __block est un type C et que vous ne pouvez donc pas ajouter de catégories.
Correction: __ bloc est un identifiant dans le compilateur C pas un typlef. P>
Je ne suis pas sûr que cela atteindra Ce que vous pensez que cela, n'infort que je ne suis même pas tout à fait sûr de ce qu'il fait: p> L'identifiant __block indique à la compliance que la variable doit être mutable dans les blocs de référencement et devrait être préservé si un bloc de référencement est copié sur le tas. Ce qui me confond de votre code est que __block est généralement utilisé pour envelopper une variable, pas un bloc lui-même. p> p>
__ bloc code> me permet de passer
ablock code> dans le bloc. J'ai renommé le bloc et j'ai oublié de renommer les références
fib code>.
Les blocs sont en réalité des types C et des types d'objectifs. Vous pouvez associer des objets avec eux à l'aide d'API d'exécution OBJC, vous pouvez les mettre dans les collections OBJC, etc. et pourtant elles sont toujours valables dans des programmes C-seul uniquement. C'est un bit net de travail de compatibilité délicat par le compilateur et les gens d'exécution :)
Un bloc qui vale d'être une instance de type afin de créer une catégorie d'une classe, le Le compilateur doit pouvoir voir l'original cet article et Cet article contient des informations utiles sur la mise en œuvre de blocs. P> à votre point d'origine, pourquoi ne pas simplement créer une catégorie de mis à jour p> p> Disons que vous pouvez em> Ajouter une catégorie à la Objet block. Comment allez-vous appeler le bloc de la méthode de la catégorie? Au meilleur de ma compréhension, la seule façon d'appeler un bloc est via l'opérateur Je ne vous recommande pas de faire cela, mais les travaux suivants ... P> __ nsglobalblock __ code>, comme on le voit dans l'extrait suivant:
@interface code> Déclaration de la classe. Je ne trouve pas la déclaration pour
__ nsglobalblock __ code> et probablement pour une bonne raison. P>
nsarray Pour votre
MapTo code> Méthode? Il semble être un meilleur endroit pour ce type de fonctionnalité. P>
() code> (E.G.,
ablock () code>). Je ne pense pas qu'il y ait un moyen de dire à l'objet de bloc, le nombre et les types de paramètres. Donc, quels arguments passeriez-vous à l'invocation des blocs? P>
@interface NSObject (BlockExtension)
- (void)foo;
@end
@implementation NSObject (BlockExtension)
- (void)foo
{
// not sure how else to determine if self is a Block since neither
// __NSGlobalBlock__ nor any of its superclasses (except NSObject)
// are accessible to the compiler
if ([[[self class] description] isEqual:@"__NSGlobalBlock__"])
{
NSLog(@"foo");
// now what?
// can't call self(), it doesn't compile
// how else can I invoke this block?
}
}
@end
...
void (^aBlock)(void) = ^(void) {
NSLog(@"Hello world");
};
// prints "foo"
[aBlock foo];
J'utilisais juste Mapto code> à titre d'exemple. Je peux penser à une demande assez importante pour une telle catégorie: la composition de la fonction, le currying, etc.
Intelligent, oui, mais dangereux. Il n'y a aucune garantie que les différentes classes NSBLOCK inhérentes à NsObject pour toujours ...
@PWC est correct en ce que vous ne pouvez pas créer une catégorie pour une classe que vous ne pouvez pas voir.
Cependant ... p>
__ nstackblock code>, __ nsmallocblock code>, __ nsautoblock code> et nsblock code>. Li>.
- Une autre introspection montre que les classes prometteuses hériter de
nsblock code> li>
ol> Il semble que tout bloc fonctionne d'une instance ou d'une sous-classe de nsblock code>. p> Vous pouvez créer une méthode sur un objet, comme le cas échéant: p> xxx pré> puis au moment de l'exécution, vous pouvez déplacer cette méthode dans la classe nsblock code> Classe: p> xxx pré> Après cela, les blocs devraient répondre au message dofoo code>. P> Utilisez à vos risques et périls, et uniquement pour expérimenter. H1> P>
Yikes! :) Une autre option consiste à simplement faire une catégorie sur NsObject code>, et promettez uniquement de l'utiliser sur des blocs ... De toute façon, c'est un peu effrayant, et je préférerais la sécurité du
[Utilitaire Quelque chosewithblock: bloquer] code> et
[ARR Carte: bloquer] code> sur la peur de
[bloquer dosshanging] code> et
[bloquer la carte: arr] < / code> ...
Alien peut-être, mais pas effrayant. Ceci est très courant dans Smalltalk, qui a inspiré l'objectif-c. Il n'y a pas de syntaxe de contrôle dans Smalltalk. Donc, une déclaration IF ressemblerait à [^ bool {retour A> 1} iftrue: ^ {...}] (sauf un nettoyant de lot dans SmallTalk: [A> 1] Sitrue: [...].)
Mais (corrigez-moi si je me trompe), les objets de blocage ne sont pas réellement garantis de descendre de NsObject code> ...
@Jonathan Je ne suis pas sûr de Garanti i>, mais l'introspection d'exécution montre que la classe privée nsblock code> classe est i> une sous-classe de
NsObject code>. Cela fonctionne donc pour le violon, mais (comme je le dis dans le poteau), il est au-delà de stupide d'utiliser ceci dans n'importe quelle sorte de réglage de la production.
Dave Delong a raison, vous ne pouvez pas ajouter une catégorie sur une classe que vous ne pouvez pas voir, mais comme les blocs sont des sous-classes de maintenant vous peut 'voir' toujours probablement pas la meilleure chose à faire dans le code qui est réellement utilisé en production ... p> p> nsblock code> Ajout:
nsblock code> et ajouter une catégorie dessus, par exemple: p>
WRONG: A block winds up being an instance of type __NSGlobalBlock__, as seen in the following snippet: int i = 0; id o = [class self]; void (^aBlock)(void) = ^(void) { [o setValue:0]; NSLog(@"Hello world %d", i); }; // prints "type = __NSGlobalBlock__" // Now it prints __NSStackBlock__ // and when moved into HEAP prints __NSMallocBlock__ NSLog(@"type = %@", [aBlock class]); It is only OKAY to say that a block winds up being an instance of type "NSGlobalBlock" unless there are no captured variables in the scope, otherwise it will be created in the STACK and when it is copied that will move the block into HEAP and every reference will be retained!
Incidemment, j'ai commencé à travailler sur une bibliothèque de l'objectif-C qui ajoute une carte et des fonctions associées à
Nsarray code> et
nsset code>: GITUB.COM/MDIPPERY/Collections
@MIPADI: Êtes-vous au courant de la carte existante comme fonctionnalité par ex.
-EnumerateObjectSouxBlock: code> et
Valurforkey: code>
@JeremyP: Oui, mais (a) Ce n'est que sur 10.6, et (b) Je suis en train de mettre en œuvre le reste du protocole de collections SmallTalk, ainsi que certaines fonctionnalités de la classe énumérable de Ruby.