我试图用我的c ++ .h文件和shared_ptr:s一起实现一个类。
为什么我的shared_ptr(totPtr)在方法之间保持其值?
当我使用double而不是类时的示例代码:
#include <memory>
static std::shared_ptr<myCppClass> totPtr;
static double tot;
@implementation ViewController
- (void) createSelf
{
totPtr = std::make_shared<myCppClass>(5);
tot = 10;
}
此方法在createSelf:
之后调用- (void)otherMethod
{
tot += 1; // works, tot = 11
totPtr->doStuff(); // doesn't work, totPtr = nullptr
}
tot2仍然具有值= 0,但是tot具有值= 10
答案 0 :(得分:2)
对于全局变量,您应该在+[initialize]
中初始化它,这是一种初始化任何全局变量的线程安全方法
+ (void)initialize {
if (self == [ViewController self]) { // need to guard it so not get called again from subclass
totPtr = std::make_shared<MyClass>();
tot = 10;
}
}
如果您在viewDidLoad
初始化它们,它现在可能有效,但当您决定拥有ViewController
的多个实例时,您会发现viewDidLoad
的第二次调用将重置这些全局变量
但是通常你不想要全局变量,你想要实例变量/属性
@interface ViewController ()
@property (nonatomic) double tot;
@end
@implementation ViewController {
std::shared_ptr<myCppClass> _totPtr;
}
你可以在另一个答案中描述的viewDidLoad
中对它们进行初始化。
注意:我不建议使用带有C ++类的ObjC属性(即shared_ptr
)。因为每次通过属性访问它时,都需要调用setter / getter方法的开销,这可能需要复制shared_ptr
,这是一个扩展操作(你应该总是通过方法参数中的引用传递shared_ptr
,但是这在ObjC中并没有得到很好的支持。直接访问ivar可以避免开销。
答案 1 :(得分:1)
最好不要使用全局变量 - 最好使用属性。
但是如果你仍然需要它 - 不要使用init方法。
在你的代码上,我看不到谁在调用createSelf方法。
这里我展示了工作代码。
#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
<强>更新强>
如果要在init * method
中初始化该var,可以使用此方法- (instancetype)initWithCoder:(NSCoder *)coder*