Créer/Affecter une CGImageRef

Philippe49Philippe49 Membre
janvier 2008 modifié dans API AppKit #1
Quelqu'un a une idée ?

Je construit une CGImageRef
NSString * imagePath=[NSHomeDirectory() stringByAppendingString:@/Pictures/aquadavinci_ii.jpg];
NSData * imageData =[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:imagePath]];
NSBitmapImageRep * bitmapImageRep=[NSBitmapImageRep imageRepWithData:imageData];
imageRef=[bitmapImageRep CGImage];  // déclarée : CGImageRef imageRef;

Je l'affecte à  la property contents d'un CALayer dont la doc est :

@property(retain) id contents
Discussion
A layer can set this property to a CGImageRef to display the image as its contents. The default value is nil.

imageLayer.contents=imageRef;

Et il me jette à  la figure un :
Warning : passing argument 1 of setContents  from incompatible pointer type]


Question 2:
Il n'y a pas plus court pour créer une CGImageRef à  partir d'un fichier jpg ?
«1

Réponses

  • psychoh13psychoh13 Mothership Developer Membre
    janvier 2008 modifié #2
    Pour éviter le warning tu peux caster ta CGImageRef en id, ça marchera normalement.
    Tous les types référence déclaré en C (CGImageRef, CGColorSpaceRef, etc.) sont capables de recevoir des messages Objective-C, ils correspondent à  des id eux aussi.

    Pour la question 2, tu peux te tourner du côté de la fonction : CGImageCreateWithJPEGDataProvider()
  • BruBru Membre
    21:19 modifié #3
    dans 1199267715:

    Question 2:
    Il n'y a pas plus court pour créer une CGImageRef à  partir d'un fichier jpg ?


    dans 1199268959:

    Pour la question 2, tu peux te tourner du côté de la fonction : CGImageCreateWithJPEGDataProvider()


    Le classique du genre :
    <br />- (CGImageRef)LoadJPEGImageIntoCGImageFromPath:(NSString *)path<br />{<br />&nbsp; &nbsp; CGDataProviderRef data=CGDataProviderCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path]);<br />&nbsp; &nbsp; CGImageRef img=CGImageCreateWithJPEGDataProvider(data, NULL, NO, kCGRenderingIntentDefault);<br />&nbsp; &nbsp; CFRelease(data);<br /><br />&nbsp; &nbsp; return img;<br />}<br />
    


    Moins de lignes, plus rapide, mais pas forcément plus clair au sein du code Obj-C/cocoa.

    .
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #4
    Précision : Tous les types C finissant en ...Ref on pour classe "NSCFType" qui est une sous-classe de NSObject.
  • Philippe49Philippe49 Membre
    21:19 modifié #5
    dans 1199269692:

    Précision : Tous les types C finissant en ...Ref on pour classe "NSCFType" qui est une sous-classe de NSObject.


    Effectivement, le cast élimine le warning.
    Mais avec cette précision, je ne comprends plus : toute sous-classe de NSObject n'est-elle pas compatible avec (id) ?
    D'ailleurs pour pour CGImageRef, il faut importer <ApplicationServices/ApplicationServices.h>

  • schlumschlum Membre
    21:19 modifié #6
    Je connais CFTypeRef, CFTypeID, mais NSCFType, ça doit être une nouveauté de Leopard  ???
    ça m'étonne NS et CF accolés ; ça n'avait jamais été fait encore ça !
  • Philippe49Philippe49 Membre
    21:19 modifié #7
    dans 1199269536:

    Moins de lignes, plus rapide, mais pas forcément plus clair au sein du code Obj-C/cocoa.


    Merci 
  • BruBru Membre
    21:19 modifié #8
    dans 1199270923:

    Je connais CFTypeRef, CFTypeID, mais NSCFType, ça doit être une nouveauté de Leopard  ???
    ça m'étonne NS et CF accolés ; ça n'avait jamais été fait encore ça !


    NSCFType est une classe cocoa (de Foundation) aussi vieille que...
    Elle est une des pierres angulaire du tool-free bridging entre CoreFoundation et cocoa.

    Cette classe (du moins ses instances) permet d'utiliser pleinement le runtime Obj-C sur des CFType.
    Par exemple un [CFType release] sera transformé en CFRelease(CFType).

    .
  • schlumschlum Membre
    janvier 2008 modifié #9
    Dingue, j'en retrouve aucune trace sur ma machine... Que ça soit avec Spotlight ou avec la complétion Xcode  ???

    [Edit] Si, en fait ça apparaà®t dans le binaire de Foundation... Mais dans aucun des headers.
  • psychoh13psychoh13 Mothership Developer Membre
    janvier 2008 modifié #10
    Normal que tu n'en trouves aucune trace, c'est une classe privée, c'est-à -dire une classe dont tu n'as pas l'interface, et si tu n'as pas l'interface d'une classe tu ne peux pas l'utiliser.

    Par exemple, quand tu utilises la classe NSString, tu ne crées jamais d'instance de NSString directement, tout simplement parce que c'est une classe abstraite et qu'elle est incapable de stockée quoique ce soit. Par contre, les méthodes d'allocations vont créer des objets de type NSCFString qui est une sous-classe de NSString, et qui correspond exactement à  une CFString.

    dans 1199270885:

    Effectivement, le cast élimine le warning.
    Mais avec cette précision, je ne comprends plus : toute sous-classe de NSObject n'est-elle pas compatible avec (id) ?
    D'ailleurs pour pour CGImageRef, il faut importer <ApplicationServices/ApplicationServices.h>


    Tout simplement parce que CGImageRef N'est PAS un objet Objective-C, il s'agit d'un pointeur sur une structure C :
    typedef struct CGimage *CGImageRef;
    Mais le C est très laxiste, tu peux facilement faire passer une structure pour un objet Objective-C, il suffit simplement que certains points correspondent...

    Voilà  comment tu peux procéder, par exemple je voudrais créer un type d'entier sous forme d'objet mais à  la manière des CFType.

    Pour refaire ce système, il faut une classe privée qui va représenter tous les objets, et tous le stypes que l'on veut faire passer pour des objets, voici un petit code amusant :

    // MyCType.h :<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />// Notre référence<br />typedef struct MyType *MyTypeRef;<br /><br />// Pour créer un objet<br />MyTypeRef MyTypeCreateWithInteger(int var);<br />// Pour accéder à  sa variable d&#39;instance<br />int MyTypeValue(MyTypeRef obj);<br /><br />// MyCType.m :<br />#import &quot;MyCType.h&quot;<br /><br />// Notre véritable structure<br />struct MyType {<br />	// Un pointeur sur la classe pour que la structure<br />	// corresponde bien à  un type Objective-C<br />	Class isa;<br />	int var;<br />};<br /><br />// Notre classe privée, elle n&#39;a rien de spécial à  déclarer<br />// Elle est juste là  pour permettre à  nos références de fonctionner<br />// comme des objets Objective-C normaux<br />@interface MyCType : NSObject<br />@end<br /><br />@implementation MyCType<br />@end<br /><br />// Pour créer un objet :<br />MyTypeRef MyTypeCreateWithInteger(int var)<br />{<br />	/* Cette fonction C est utilisée par +allocWithZone: pour créer des objets Objective-C<br />	 * Ici, nous l&#39;utilisons directement, on indique notre classe MyCType,<br />	 * L&#39;ennuie c&#39;est que si on l&#39;utilise de la même manière que +allocWithZone:<br />	 * notre objet n&#39;aura pas suffisamment de mémoire pour contenir notre variable d&#39;instance<br />	 * c&#39;est pour cette raison qu&#39;on utilise le paramètre extra-bytes, pour dire à <br />	 * NSAllocateObject() d&#39;ajouter la taille de notre variable d&#39;instance en plus<br />	 * Cette fonction s&#39;occupera elle-même de mettre la bonne valeur au pointeur isa<br />	 * de notre structure, et on pourra par la même occasion bénéficier du système<br />	 * retain/release/autorelease.<br />	 */<br />	MyTypeRef new = NSAllocateObject([MyCType class], sizeof(struct MyType) - sizeof(Class), NSDefaultMallocZone());<br />	new-&gt;var = var;<br />	return new;<br />}<br /><br />int MyTypeValue(MyTypeRef obj)<br />{<br />	return obj-&gt;var;<br />}
    


    Voici le code de test :
    #import &lt;Foundation/Foundation.h&gt;<br />#import &lt;ApplicationServices/ApplicationServices.h&gt;<br />#import &quot;MyCType.h&quot;<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />	<br />	MyTypeRef o = MyTypeCreateWithInteger(100);<br />	<br />	NSLog(@&quot;Value = %d, Object = %@, retain = %d&quot;,<br />		&nbsp; MyTypeValue(o), [o class], [o retainCount]);<br />	<br />	[o retain];<br />	NSLog(@&quot;Retain = %d&quot;, [o retainCount]);<br />	[o autorelease];<br />	<br />	[o release];<br />	<br />	[pool release];<br />&nbsp; &nbsp; return 0;<br />}
    


    Bon vous aurez plein de warning, mais ça fonctionnera et vous aurez comme résultat :
    2008-01-02 12:51:37.793 FoundationTest[1610:10b] Value = 100, Object = MyCType, retain = 1<br />2008-01-02 12:51:37.806 FoundationTest[1610:10b] Retain = 2
    
  • schlumschlum Membre
    janvier 2008 modifié #11
    Oui, je viens de voir avec le class-dump de Foundation toutes les classes privées NSCF...
    Je pensais que l'identification entre la structure C des types CF et l'objet NS correspondant suffisait pour le toll-free bridging.
    Puisqu'en interne de toute façon, que ça soit structure, objet Obj-C ou objet C++, même combat.

    (mais c'est vrai qu'il faut aussi que ça fonctionne dans l'autre sens : transformer les appels de méthodes en appels de fonctions C, sinon le pont est à  sens unique).
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #12
    C'est-à -dire que le type de l'objet sera CFString et la classe de l'objet sera NSCFString, c'est simplement une classe privée que l'on crée pour que le runtime Objective-C soit capable d'utiliser ces objets.

    (regarde mon message précédent je l'ai éditée pour ajouter une simulation de type C correspondant à  une classe Objective-C.)
  • BruBru Membre
    21:19 modifié #13
    dans 1199274609:

    Oui, je viens de voir avec le class-dump de Foundation toutes les classes privées NSCF...
    Je pensais que l'identification entre la structure C des types CF et l'objet NS correspondant suffisait pour le toll-free bridging.
    Puisqu'en interne de toute façon, que ça soit structure, objet Obj-C ou objet C++, même combat.

    (mais c'est vrai qu'il faut aussi que ça fonctionne dans l'autre sens : transformer les appels de méthodes en appels de fonctions C, sinon le pont est à  sens unique).


    Les classes NSCF sont utiles pour le toll-free bridging de CoreFoundation vers cocoa.

    Dans la plupart des cas, le toll-free bridging sert de cocoa vers CF (genre je créé un objet cocoa, je caste, puis je lui applique une fonction CF).

    Les NSCF permettent exactement l'inverse : je créé un CFType (dans CF), puis je caste en id, enfin je l'utilise comme un objet cocoa (donc je lui envoie des messages).

    .
  • psychoh13psychoh13 Mothership Developer Membre
    janvier 2008 modifié #14
    Les classes NSCF ne sont pas utiles que pour le toll-free bridging, elles permettent aussi de faire passer des objets n'ayant pas de classe correspondante (par exemple CGImageRef) pour des objets Objective-C.
    ça permet notamment d'utiliser sans contraintes les messages retain/release/autorelease.
  • schlumschlum Membre
    21:19 modifié #15
    dans 1199275406:

    Les classes NSCF ne sont pas utiles que pour le toll-free bridging, elles permettent aussi de faire passer des objets n'ayant pas de classe correspondante (par exemple CGImageRef) pour des objets Objective-C.
    ça permet notamment d'utiliser sans contraintes les messages retain/release/autorelease.


    Oui, ça s'appelle le... toll-free bridging  ;) (Sens CF -> Cocoa ; voir message de Bru ci-dessus)
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #16
    dans 1199275871:
    Oui, ça s'appelle le... toll-free bridging  ;) (Sens CF -> Cocoa ; voir message de Bru ci-dessus)


    Non, le toll-free bridging permet seulement d'utiliser un CFString comme une NSString et vice-versa, ou bien un NSDictionary comme un CFDictionary. C'est-à -dire qu'à  chaque méthode correspond exactement la même fonction qui peut s'utiliser sur les deux types d'objets.
    Moi je parle de pouvoir utiliser certaines fonctionnalités disponible dans Cocoa sur n'importe quel type CF... CG... etc. Sans qu'il y ait pour autant une correspondance total avec une quelconque classe publique.
  • schlumschlum Membre
    janvier 2008 modifié #17
    dans 1199276058:
    Moi je parle de pouvoir utiliser certaines fonctionnalités disponible dans Cocoa sur n'importe quel type CF... CG... etc. Sans qu'il y ait pour autant une correspondance total avec une quelconque classe publique.


    Exemple ?
    J'ai du mal à  suivre là ...
    Les types NSCF correspondent exactement aux types "interchangeables"
    http://developer.apple.com/documentation/Cocoa/Conceptual/CarbonCocoaDoc/Articles/InterchangeableDataTypes.html

    J'ai l'impression que ce dont tu parles fait aussi partie du toll-free bridging.
  • BruBru Membre
    21:19 modifié #18
    Vous avez raison tous les 2.

    Certains CFType n'ont pas d'équivalent cocoa, donc pas de toll-free bridging.

    Mais pour pouvoir utiliser ces CFType sous cocoa, une pseudo-classe (NSCF) est alors implantée pour avoir à  nouveau la possibilité de faire du tool-free bridging.

    .

  • schlumschlum Membre
    janvier 2008 modifié #19
    Si je comprends bien, ça serait utiliser les méthodes de NSCFType et NSCFType__ en dehors du cadre du toll-free bridging ?
    Sur n'importe quel CF*Ref via un cast (id) par exemple ?

    J'ai déjà  vu plus propre comme programmation quand même  ???
  • BruBru Membre
    21:19 modifié #20
    dans 1199277005:

    Si je comprends bien, ça serait utiliser les méthodes de NSCFType et NSCFType__ en dehors du cadre du toll-free bridging ?
    (sur n'importe quel objet ?)
    Y a plus propre comme programmation quand même  ???


    Je serais curieux de lire ce que tu nommes "cadre du toll-free bridging".

    Le pur toll-free bridging c'est ce qu'a dit Psycho, c'est d'avoir une "structure" qui passe pour un objet cocoa ou pour un CFtype indifféremment.

    Les classes NSCF font parties du mécanisme toll-free bridging. Mais pour les CFTypes qui n'ont pas d'équivalent sous cocoa (par exemple NSBundle/CFBundle), une pseudo-classe NSCF est utilisée.
    Ces pseudo-classes ne permettent pas de se substituer au CFtype sous-jacent (il sera toujours obligatoire d'utiliser les fonctions propres à  ce type, car pas d'équivalent en méthode cocoa).

    il y a des avantages à  utiliser parfois les NSCF : par exemple c'est de pouvoir utiliser l'autoreleasepool sur ces CFType via leur déguisement en NSCF (il n'y a pas d'autoreleasepool dans CoreFoundation).

    Enfin, "programmation propre" : c'est un vaste débat !

    .
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #21
    Le toll-free bridging est en fait une partie de ce dont je parle. Tout type ou classe permettant du toll-free bridging est conçu de la même manière que tout CFType, ce qu'ajoute en fait le toll-free bridging c'est en fait qu'il existe une classe en Cocoa qui a pour variables d'instances exactement les mêmes champs que son type correspondant.
    Alors que pour les CFTypes qui n'ont pas de correspondance en Objective-C, la seule chose qu'ils ont (à  priori) c'est le champ de type Class permettant au runtime de les utiliser comme des objets.

    Sinon, je parlerais pas de programmation propre mais plutôt de facilitation, les frameworks Apple sont conçus pour permettre une pleine et entière utilisation de la programmation orientée-objet dans le carde C/Objective-C.
  • Philippe49Philippe49 Membre
    21:19 modifié #22
    dans 1199278078:

    c'est d'avoir une "structure" qui passe pour un objet cocoa ou pour un CFtype indifféremment.

    ...

    il y a des avantages à  utiliser parfois les NSCF : par exemple c'est de pouvoir utiliser l'autoreleasepool sur ces CFType via leur déguisement en NSCF (il n'y a pas d'autoreleasepool dans CoreFoundation).


    La question que je me pose ci, c'est y a-t-il physiquement un objet créé en proxy pour la CGImageRef ? ou est-ce que c'est à  l'adresse en dur que la référence est prise ?


    Quand au warning quelle est sa raison d'être:
    • attention, vous utilisez une classe non documentée ?  
    • attention, je ne trouve pas isa ?  
    • ... ?  
  • schlumschlum Membre
    21:19 modifié #23
    dans 1199278078:

    Je serais curieux de lire ce que tu nommes "cadre du toll-free bridging".

    Le pur toll-free bridging c'est ce qu'a dit Psycho, c'est d'avoir une "structure" qui passe pour un objet cocoa ou pour un CFtype indifféremment.


    Oui, c'est exactement ça... C'est les équivalences données par la doc "InterchangeableDataTypes" (lien donné au dessus)
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #24
    dans 1199278692:
    La question que je me pose ici, c'est y a-t-il physiquement un objet créé en proxy pour la CGImageRef ? ou est-ce que c'est à  l'adresse en dur que la référence est prise ?


    Je ne comprends pas très bien la question là . Regarde l'exemple que j'ai donné plus haut, c'est-à -dire comment créer un type C ...Ref à  la manière d'Apple.

    dans 1199278692:
    Quant au warning quelle est sa raison d'être:
    • attention, vous utilisez une classe non documentée ?  
    • attention, je ne trouve pas isa ?  
    • ... ?  



    Quand tu utilises une classe Objective-C normale, le compilateur sait qu'il s'agit d'un type utilisable dans les messages, en revanche, quand tu utilises un CFType, le compilateur tout ce qu'il voit c'est qu'il s'agit d'un pointeur sur une structure, et pas d'une vraie classe... Il ne sait pas que derrière, l'implémenteur du type a placé un champ de type Class utilisable par le runtime Objective-C, donc dans le doute il met un avertissement "attention ce type peut ne pas être utilisé par le runtime".
  • schlumschlum Membre
    janvier 2008 modifié #25
    Effectivement :

    #import &lt;Foundation/Foundation.h&gt;<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br /><br />	CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,(const UInt8*)&quot;/Applications/TextEdit.app&quot;,27,true);<br />&nbsp; &nbsp; CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault,url);<br />	<br />	NSLog(@&quot;%@ %@&quot;,[(id)url className],[(id)bundle className]);<br />	<br />	CFRelease(bundle);<br />	CFRelease(url);<br />	<br />&nbsp; &nbsp; [pool release];<br />&nbsp; &nbsp; return 0;<br />}
    


    -> NSURL NSCFType

    Ceci-dit, s'il "crée" une pseudo-instance, comment l'utilisation de l'AutoReleasePool s'appliquerait-elle au type CF initial ? La pseudo instance gère les deux structures ?


    Ce qui voudrait dire que ce code est correct :

    #import &lt;Foundation/Foundation.h&gt;<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br /><br />	CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,(const UInt8*)&quot;/Applications/TextEdit.app&quot;,27,true);<br />&nbsp; &nbsp; CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault,url);<br />	[(id)url autorelease];<br />	[(id)bundle autorelease];<br />	<br />	NSLog(@&quot;%@ %@&quot;,[(id)url className],[(id)bundle className]);<br />	<br />&nbsp; &nbsp; [pool release];<br />&nbsp; &nbsp; return 0;<br />}
    


    (c'est ça que j'appelle du code pas très propre  :o)
  • psychoh13psychoh13 Mothership Developer Membre
    21:19 modifié #26
    La réponse est dans le code que j'ai exposé plus haut, c'est-à -dire celui-ci :

    // MyCType.h :<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />// Notre référence<br />typedef struct MyType *MyTypeRef;<br /><br />// Pour créer un objet<br />MyTypeRef MyTypeCreateWithInteger(int var);<br />// Pour accéder à  sa variable d&#39;instance<br />int MyTypeValue(MyTypeRef obj);<br /><br />// MyCType.m :<br />#import &quot;MyCType.h&quot;<br /><br />// Notre véritable structure<br />struct MyType {<br />	// Un pointeur sur la classe pour que la structure<br />	// corresponde bien à  un type Objective-C<br />	Class isa;<br />	int var;<br />};<br /><br />// Notre classe privée, elle n&#39;a rien de spécial à  déclarer<br />// Elle est juste là  pour permettre à  nos références de fonctionner<br />// comme des objets Objective-C normaux<br />@interface MyCType : NSObject<br />@end<br /><br />@implementation MyCType<br />@end<br /><br />// Pour créer un objet :<br />MyTypeRef MyTypeCreateWithInteger(int var)<br />{<br />	/* Cette fonction C est utilisée par +allocWithZone: pour créer des objets Objective-C<br />	 * Ici, nous l&#39;utilisons directement, on indique notre classe MyCType,<br />	 * L&#39;ennuie c&#39;est que si on l&#39;utilise de la même manière que +allocWithZone:<br />	 * notre objet n&#39;aura pas suffisamment de mémoire pour contenir notre variable d&#39;instance<br />	 * c&#39;est pour cette raison qu&#39;on utilise le paramètre extra-bytes, pour dire à <br />	 * NSAllocateObject() d&#39;ajouter la taille de notre variable d&#39;instance en plus<br />	 * Cette fonction s&#39;occupera elle-même de mettre la bonne valeur au pointeur isa<br />	 * de notre structure, et on pourra par la même occasion bénéficier du système<br />	 * retain/release/autorelease.<br />	 */<br />	MyTypeRef new = NSAllocateObject([MyCType class], sizeof(struct MyType) - sizeof(Class), NSDefaultMallocZone());<br />	new-&gt;var = var;<br />	return new;<br />}<br /><br />int MyTypeValue(MyTypeRef obj)<br />{<br />	return obj-&gt;var;<br />}
    
  • BruBru Membre
    21:19 modifié #27
    dans 1199279648:

    Ceci-dit, s'il "crée" une pseudo-instance, comment l'utilisation de l'AutoReleasePool s'appliquerait-elle au type CF initial ? La pseudo instance gère les deux structures ?


    Non, le mécanisme du tool-free bridging ne fonctionne pas comme ça.

    Disons que chaque structure C (opaque) CFType commence par un pointeur non-utilisé par les fonction CF, mais qui se nomme isa...
    La structure C d'un objet Obj-C commence aussi par un pointeur isa...

    Voilà  le secret du bridging !
    Bon c'est plus complexe que ça, mais la base est là  : la même structure peut être utilisée par les 2 environnements CF et Obj-C...

    .
  • Philippe49Philippe49 Membre
    21:19 modifié #28
    dans 1199280189:

    Disons que chaque structure C (opaque) CFType commence par un pointeur non-utilisé par les fonction CF, mais qui se nomme isa...
    La structure C d'un objet Obj-C commence aussi par un pointeur isa...

    Voilà  le secret du bridging !
    Bon c'est plus complexe que ça, mais la base est là  : la même structure peut être utilisée par les 2 environnements CF et Obj-C...

    Cela réponds à  ma question 2

    Maintenant, il me reste à  lire/étudier le code de Psychoh qui m'a l'air particulièrement instructif
  • schlumschlum Membre
    janvier 2008 modifié #29
    dans 1199280189:

    dans 1199279648:

    Ceci-dit, s'il "crée" une pseudo-instance, comment l'utilisation de l'AutoReleasePool s'appliquerait-elle au type CF initial ? La pseudo instance gère les deux structures ?


    Non, le mécanisme du tool-free bridging ne fonctionne pas comme ça.

    Disons que chaque structure C (opaque) CFType commence par un pointeur non-utilisé par les fonction CF, mais qui se nomme isa...
    La structure C d'un objet Obj-C commence aussi par un pointeur isa...

    Voilà  le secret du bridging !
    Bon c'est plus complexe que ça, mais la base est là  : la même structure peut être utilisée par les 2 environnements CF et Obj-C...

    .


    Dans le debugger, si je fais un "p bundle->isa", j'obtiens ça :"There is no member named isa".
    C'est parce qu'il n'est pas capable d'aller le récupérer ?  ???

    [Edit]
    Effectivement, même adresse pour les deux :
    (gdb) p bundle<br />$6 = (CFBundleRef) 0x303340<br />(gdb) p objCBundle<br />$7 = (struct objc_object *) 0x303340<br />(gdb) p bundle-&gt;isa<br />There is no member named isa.<br />(gdb) p objCBundle-&gt;isa<br />$8 = (struct objc_class *) 0xa07c45bc
    
  • schlumschlum Membre
    janvier 2008 modifié #30
    Le "struct objc_class *" est alloué tout le temps ???
    Bravo l'économie mémoire  :P

    (gdb) p ((void**)bundle)[0]<br />$12 = (void *) 0xa07c45bc
    
  • BruBru Membre
    21:19 modifié #31
    dans 1199280657:

    Dans le debugger, si je fais un "p bundle->isa", j'obtiens ça :"There is no member named isa".
    C'est parce qu'il n'est pas capable d'aller le récupérer ?  ???


    J'ai simplifié mes explications pour la clarté du propos.

    Chaque structure CFType commence par une structure CFRuntimeBase (c'est elle qui contient le "membre isa").
    Je ne me souviens plus du nom de la structure dans CFType.

    Et c'est hautement non documenté...
    Faut fouiller dans les sources Darwin (où le framework CF est en open) pour en savoir plus.

    .
Connectez-vous ou Inscrivez-vous pour répondre.