2010-07-22 6 views
2

Je suis principalement un développeur C++, récemment j'écris des applications iPhone.Un std :: tr1 :: shared_ptr pour Objective C++ sur iPhone?

La gestion de la mémoire sur l'iPhone est OK pour moi, en raison de la limitation des ressources, il est conseillé d'utiliser des compteurs de référence plutôt que de copier en profondeur. Un problème est que je dois gérer les compteurs de référence moi-même: alloc signifie counter = 1; Je souhaite écrire une classe shared_ptr like pour Cocoa Touch, donc je dois rarement manipuler manuellement les compteurs de référence par moi-même.

Je doute qu'il ya un code existant pour cela, et je voudrais entendre quelques conseils, aujourd'hui est le 5ème jour depuis que je commencé à apprendre c

objectif Merci.

+0

Je recommande vivement de ne pas faire cela, et d'apprendre à la place la façon appropriée de gérer la mémoire via Objective-C/Cocoa. La raison en est que Cocoa-Touch pousse et affiche des vues (qui conservent et libèrent du code) et ne respectera pas votre code. –

+0

Objectif C++? Je ne pense pas que ce soit réel. – nmichaels

+3

Objective-C++ existe: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html#//apple_ref/doc/uid/TP30001163-CH10-SW1 – JBRWilkinson

Répondre

1

Tant que vous apprenez d'abord les règles de gestion de la mémoire, il n'y a pas vraiment de problème avec shared_ptr - il peut vous aider dans les contextes C++ mais ne laisse pas les questions de propriété disparaître comme par magie.
shared_ptr supporte un deallocator personnalisé pour les éléments suivants:

@interface A : NSObject 
- (void)f; 
@end 

@implementation A 
- (void)dealloc { NSLog(@"bye"); [super dealloc]; } 
- (void)f { NSLog(@"moo"); } 
@end 

void my_dealloc(id p) { 
    [p release]; 
} 

// ... 
{ 
    shared_ptr<A> p([[A alloc] init], my_dealloc); 
    [p.get() f]; 
} 

... Sorties:

moo
bye

... comme prévu.

Si vous voulez, vous pouvez cacher la deallocator de l'utilisateur en utilisant une fonction d'assistance, par exemple:

template<class T> shared_ptr<T> make_objc_ptr(T* t) { 
    return shared_ptr<T>(t, my_dealloc); 
} 

shared_ptr<A> p = make_objc_ptr<A>([[A alloc] init]); 
+0

Georg, merci pour l'aide !!! C'est une bonne réponse. Une chose mineure, si j'utilise shared_ptr en tant que membre dans une classe Cocoa [un peu de Controller ou UIView], je ne peux pas profiter de la propriété et de la fonctionnalité synthétisée d'obj c ... Je ne sais pas ce qui se passera si je viens les deux ensemble ... – shader

+0

@shader: Je ne le ferais pas et garderais plutôt les langages séparés autant que possible car leurs règles de vie et d'initialisation ne sont pas très sympas ensemble. Rob Napier avait un post sur la même chose que je ferais pour [envelopper C++ avec ObjC] (http://robnapier.net/blog/wrapping-c-take-2-1-486), [partie 2 ici] (http://robnapier.net/blog/wrapping-c-take-2-2-493). Les pointeurs intelligents pour les instances ObjC sont pour moi particulièrement intéressants pour les utiliser dans des contextes C++. –

+0

Après réflexion, un pointeur partagé pour l'encapsulation des instances ObjC est en réalité exagéré car elles sont déjà référencées - un 'intrusive_ptr' qui ne fait pas de ref-count séparé serait meilleur. Mais cela a une ou deux autres complexités que je vais devoir examiner le week-end ou la semaine prochaine. –

0

La gestion des ressources dans Cocoa peut être difficile: certains appels d'API conservent automatiquement une référence et d'autres pas, certains retournent un objet autoreleased, d'autres un objet retenu. En protégeant cela dans une classe shared_ptr, vous aurez plus de chances de faire des erreurs. Mon conseil est de prendre d'abord la route "normale" de cacao jusqu'à ce que vous soyez assez expérimenté.

1

Vous avez oublié le cas 4

[4] vous devez passer un pointeur vers un objet sur une méthode que la valeur de retour.

C'est ici que vous devez -autorelease.

Je vous suggère de lire le memory management rules et d'écrire du code réel avant d'essayer ce petit projet afin de vous faire une idée de la façon dont la gestion de la mémoire est supposée fonctionner.

+0

Je pense que je suis votre point: Si la fonction ne retourne que le pointeur de membre, ce serait OK, coz quelqu'un prendra soin: - (UIButton *) getButton() { m_button_ptr de retour; } Mais si elle renvoie une variable allouée locale, il convient d'ajouter à la piscine, et la piscine se terminera finalement: - (UIButton *) getButton() { UIButton * BTN = [[UIButton alloc] init]; [autortease Btn]; return btn; } Merci! : D – shader

0

Avez-vous examiné [object autorelease]? Peut-être que cela rendrait les choses un peu plus faciles.

1

comptage de référence automatique, venir dans iOS 5, fera efficacement tout pointeur vers un acte d'objet c objectif comme un pointeur intelligent. Les appels retenus/relâchés seront synthétisés par le compilateur sur assign et deallocation, sauf si vous déclarez explicitement qu'une référence est faible, auquel cas ils seront automatiquement remis à zéro lorsque l'objet est désalloué.

Mon conseil est d'attendre quelques mois pour cela.Vous pourriez être en mesure de mettre en place quelque chose de similaire entre-temps, mais je recommanderais de ne pas le faire. D'une part, ça va être moche. Exemple:

smart_ptr<id> array = make_smart_ptr([NSMutableArray array]); 

NSUInteger count = [array count];   // won't work. 
count = [array.get() count];     // works, but yuck. 
[array.get() setArray: anotherArray.get()]; // even more yuck. 

De plus, si vos en-têtes sont pleines de classes C++, vous devrez compiler l'ensemble de votre projet en Objective-C++, ce qui peut vous causer des problèmes comme objectif-C++ est pas 100% compatible avec code objectif-c, et tous les frameworks tiers ne fonctionneront pas correctement avec. Et oubliez de partager votre code avec quelqu'un d'autre.

Il peut être intéressant de faire quelque chose comme ça, mais vous ne voudrez pas l'utiliser. Et faites attention à la tentation de recréer vos morceaux préférés de C++ en Objective-C. Les langues sont très différentes, et vous pourriez passer beaucoup de temps à le faire, ce qui est le temps passé à apprendre toutes les choses intéressantes que vous pouvez faire en Objective-C que vous ne pouvez pas faire en C++.

+0

C++ shared_ptr et weak_ptr sont toujours plus propres que l'implémentation native Objective-C; pas besoin de plaster votre base de code avec release et de retenir les appels, juste l'affectation et les destructeurs ptr prennent soin de tout le nettoyage et le suivi des références – lurscher