【问题标题】:Objective-C++ assigning values to OBj-C properties from C++ objectObjective-C++ 从 C++ 对象为 OBj-C 属性赋值
【发布时间】:2014-03-24 09:19:23
【问题描述】:

好的,首先,我必须承认这是我第一次接触 C++。清除后,我想继续。问题就这么简单,但有一些(奇怪的)扭曲。我正在尝试将 C++ 库包装到 Objective-C 代码中。假设名为“my_class”的C++类有一个方法“get_string”,它返回另一个类“my_second_class”,它有一个名为“my_string”的方法,它返回一个std::string,我想把它放入属性NSString为我的 Obj-C 类“MyClass”命名为“MyNSString”。

这是代码。我跳过了包含/导入和“使用命名空间”部分。它们存在。

MyClass.h

@interface Torrent : NSObject {
    my_class myCls;

@property NSString *MyNSString;

- (instancetype)initWithHandle:(void*)handle;
- (void)setInfo;

@end

MyClass.m

@implementation MyClass

@synthesize MyNSString;

- (instancetype)initWithHandle:(void*)handle {
    self = [super init];
    if (self) {
        myCls = static_cast<my_class*>(handle);
        if (! myCls->is_valid()) return nil;
        [self setInfo];
    }
    return self;
}

我还没有实现 setInfo。这就是错误开始的地方。因此,我将详细介绍我针对该问题所做的每一次尝试。

尝试 #1

- (void)setInfo {
    my_second_class mySecCls = myCls->get_string();
    MyNSString = @(mySecCls.my_string().c_str());
}

尝试 #2

- (void)setInfo {
    MyNSString = @(myCls->get_string().my_string().c_str());
}

尝试 #3

- (void)setInfo {
    my_second_class mySecCls = myCls->get_string();
    NSString *unusedString = @(mySecCls.my_string().c_str());
}

尝试#1 失败,#2 和#3 成功。 我还必须提到,有大约 75 个这样的值需要每秒钟更新一次(我在代码中使用 NSTimer),所以尝试 #2 会影响性能。 #3 显然没用,但不知何故,它起作用了。我想知道为什么 #1 失败,而 #3 和 #2 成功。

如果有人能给我一些适中(不太大也不太小)Objective-C++ 代码的链接,我将不胜感激。

编辑: 尝试 #1 导致 EXC_BAD_ACCESS 代码=1

谢谢。

【问题讨论】:

  • 请发布您的 C++ 类的代码
  • 另外,尝试 #2 的性能如何低于 #1?
  • 如果我在这里错了,请纠正我,但我假设更多的调用 = 更少的性能。所以,object = anotherObject.getObject; property1 = object.prop1;属性2 = object.prop2;优于 property1 = anotherObject.getObject.prop1; property2 = anotherObject.getObject.prop2;

标签: c++ objective-c xcode5 objective-c++


【解决方案1】:

这是我的猜测,因为我们目前缺少一些相关信息。
您的 get_string() 方法是否可能返回对 my_second_class 实例的(可能是 const)引用?
如果是这种情况,那么第一次尝试会失败,因为mySecCls 是一个本地对象,在函数返回时会被销毁。销毁发生后,MyNSString 指向堆栈上的某个无效内存位置。第二次尝试有效,因为没有创建这样的本地(即临时,从您的类的角度来看)对象,并且传递的指针指向更持久的 myCls 对象的内容。

(我还假设 my_string() 返回 const std::string&amp; 而不是 string,否则您会遇到与生成的临时变量相同的问题)。

如果你想做一些像尝试 #2,但看起来更像尝试 #1 的东西,你可以尝试:

- (void)setInfo {
    const my_second_class& mySecCls = myCls->get_string();
    MyNSString = @(mySecCls.my_string().c_str());
}

但是,这几乎等同于尝试 #1。

【讨论】:

  • 您的两个假设都是正确的。但是,这仍然不能解释成功的尝试#3。另外,如果能举个例子就更好了。正如我所说,在 C++ 方面我是个白痴。但是,我已经开始看书了。希望我能在一周内完成。天哪,我得学习 C++,不是吗?另外,如果你知道一些好的 Objective-C++ 项目,我可以从中找到这样的例子,我将不胜感激。无论如何,谢谢。
  • 尝试 #3 很可能会成功(即不会崩溃),即使行为未定义,因为编译器会优化掉您创建的本地 NSString。这只是猜测
  • 好吧,如果我们忽略尝试#2,我们可以推断错误与 MyNSString 相关。如果我们忽略尝试#3,我们推断问题出在 mySecCls 上。但是,在这种情况下,我们必须同时考虑两者。我无法确定问题所在。
  • “工作”是指行为正确,而不是“不崩溃”。尝试 #3 可能不会崩溃,但它也没有任何用处。
  • 不,我使用了断点并且分配的值是正确的。也许我们应该在聊天中讨论这个问题。有点太长了,把正确答案贴出来吧。
猜你喜欢
  • 1970-01-01
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 2011-01-29
  • 2012-02-23
  • 2012-06-16
  • 1970-01-01
相关资源
最近更新 更多