Reputation: 55
I'm trying to implement a class from my c++ .h-file together with shared_ptr:s.
Why doesn't my shared_ptr (totPtr) keep its value between the methods?
Example code when I've use a double instead of the class:
#include <memory>
static std::shared_ptr<myCppClass> totPtr;
static double tot;
@implementation ViewController
- (void) createSelf
{
totPtr = std::make_shared<myCppClass>(5);
tot = 10;
}
This method is called after createSelf:
- (void)otherMethod
{
tot += 1; // works, tot = 11
totPtr->doStuff(); // doesn't work, totPtr = nullptr
}
tot2 still has has the value = 0, but tot has the value = 10
Upvotes: 1
Views: 1622
Reputation: 46598
For global variables, you should initialized it in +[initialize]
, which is a thread-safe way to initialize any global variables
+ (void)initialize {
if (self == [ViewController self]) { // need to guard it so not get called again from subclass
totPtr = std::make_shared<MyClass>();
tot = 10;
}
}
If you initialize them in viewDidLoad
, it may works now, but when you decide to have multiple instance of ViewController
, you will find the second call of viewDidLoad
will reset these gloabl variables.
BUT normally you don't want global variable, you want instance variable / property
@interface ViewController ()
@property (nonatomic) double tot;
@end
@implementation ViewController {
std::shared_ptr<myCppClass> _totPtr;
}
which you can initailize them in viewDidLoad
which described in the other answer.
Note: I don't recommended to use ObjC property with C++ class (i.e. shared_ptr
). Because everytime you access it via property, it require overhead of call a setter/getter method which may need to copy shared_ptr
, which is an expansive operation (you should always pass shared_ptr
by reference in method argument, but this doesn't have good support in ObjC). Access ivar directly allow you to avoid the overhead.
Upvotes: 2
Reputation: 33
It is better not to use global variables - better to use properties.
But if you still need it - don't use init method for it.
On yours code i don't see who is calling createSelf method.
Here i show working code.
#import "ViewController.h"
#import "MyClass.h"
#include <memory>
static std::shared_ptr<MyClass> totPtr;
static double tot;
@interface ViewController ()
@property (nonatomic) std::shared_ptr<MyClass> p1;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self m1];
[self m2];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) m1{
totPtr = std::make_shared<MyClass>();
self.p1 = std::make_shared<MyClass>();
tot = 10;
}
-(void) m2{
NSLog(@"id: %d",self.p1->id());
NSLog(@"id: %d",totPtr->id());
}
- (IBAction)ev1:(id)sender {
[self m2];
}
@end
Update:
You could use this method if you want to init that var in init* method
- (instancetype)initWithCoder:(NSCoder *)coder*
Upvotes: 1