Objective c __结构中未恢复的不安全\u

Objective c __结构中未恢复的不安全\u,objective-c,c,Objective C,C,假设我有一个结构,我在其中声明如下: struct myStruct { NSString *aString; } 以上给出了误差 但是,我可以通过以下方式修复错误: struct myStruct { __unsafe_unretained NSString *aString; } 它会使错误静音,但会在运行时崩溃,因为我认为aString会立即被释放 我尝试了\uu strong,但它无法编译 是否有其他方法可以将对象存储在结构中并正确使用它?您可以创建一个新对象并将其用

假设我有一个结构,我在其中声明如下:

struct myStruct
{
    NSString *aString;
}
以上给出了误差

但是,我可以通过以下方式修复错误:

struct myStruct
{
    __unsafe_unretained NSString *aString;
}
它会使错误静音,但会在运行时崩溃,因为我认为aString会立即被释放

我尝试了
\uu strong
,但它无法编译


是否有其他方法可以将对象存储在结构中并正确使用它?

您可以创建一个新对象并将其用作指向结构的指针(因为这就是Objective C对象)。因此,如果您使用所需的实例变量创建NSObject的子类,则可以将其完全视为指向结构的指针(初始化后)。i、 e

如下面的注释所述,您需要在接口中声明变量,如下所示:

@interface myObjStruct : NSObject
{
  @public
  NSString *instanceVariable1;
}
struct testStruct {
  __unsafe_unretained AnyObj *obj;
};

- (void)aMethod
  AnyObj *aObj = [[AnyObj alloc] init];
  CFBridgingRetain(aObj); \\increment the retain count.

  struct testStruct test = {
    aObj,
  };

  aObj = nil;

  NSLog(@"%@", aObj); 
}
对于NSString,您可以使用CFStringRef,或者将
NSString*
强制转换为CFString并使用
CFRetain()
保留它,或者使用
CFBridgingRetain
立即获得递增的保留计数。您可以使用从CF类型(如CFArray CFDictionary)免费桥接的任何类型执行此操作

您现在拥有字符串的所有权,并且需要在某个时候调用
test.str
上的
CFRelease
,以避免内存泄漏。要获得一个
NSString
返回,您可以像这样将其转换为
NSString*string=(uu-bridge-NSString*)test.str

上面的代码增加了字符串对象的保留计数。可以将其用于任何对象,如:

@interface myObjStruct : NSObject
{
  @public
  NSString *instanceVariable1;
}
struct testStruct {
  __unsafe_unretained AnyObj *obj;
};

- (void)aMethod
  AnyObj *aObj = [[AnyObj alloc] init];
  CFBridgingRetain(aObj); \\increment the retain count.

  struct testStruct test = {
    aObj,
  };

  aObj = nil;

  NSLog(@"%@", aObj); 
}
要稍后释放此对象,您需要执行
CFRelease((uu-bridge-CFTypeRef)(test.obj))。请注意,如果删除
CfBrigingRetain(aObj)此代码可能会崩溃

您还可以尝试玩
id objc_retain(id值)虽然要使用此选项,您需要手动包含arc.h标题。请参见,您将使用此选项来增加保留值,非常类似于上面的代码,但不需要强制转换。您还必须使用等效的释放功能。

    P>桥将指针转移到Objto-C与核心基础之间,不转移所有权。

    P.>桥保持或CFBRGGIN保留向核心基础指针抛出Objto-C指针,并将所有权转移给您。你是 负责调用CFRelease或相关函数以放弃 对象的所有权

  • __bridge_transfer或CfBridgengRelease将非Objective-C指针移动到Objective-C,并将所有权转移到ARC。ARC负责 用于放弃对象的所有权

示例(不推荐)

似乎
\uuuuuuu bridge\u reserved
\uuuuu bridge\u transfer
不允许将所有权转移到同一类型。所以我使用了额外的桥来进行类型转换

我已经测试确认NSString对象没有泄漏

#define TEST_COUNT 10000

struct myStruct
{
    NSString* __unsafe_unretained aString;
};

static struct myStruct* myArray = NULL;

static void allocString()
{
    myArray = (struct myStruct*) malloc(sizeof(struct myStruct) * TEST_COUNT);
    for (int i=0; i<TEST_COUNT; ++i)
    {
        NSString* v = [[NSString alloc] initWithFormat:@"%d", i];
        myArray[i].aString = (__bridge NSString*)(__bridge_retained void*) v;
    }
}

static void freeString()
{
    if (myArray)
    {
        for (int i=0; i<TEST_COUNT; ++i)
        {
            if (myArray[i].aString)
            {
                NSString* v = (__bridge_transfer NSString*) (__bridge void*) myArray[i].aString;
                v = nil;
            }
        }
        free(myArray);
    }
}
#定义测试计数10000
结构myStruct
{
NSString*\uuuu不安全\uu未修复的收缩;
};
静态结构myStruct*myArray=NULL;
静态空隙allocString()
{
myArray=(struct myStruct*)malloc(sizeof(struct myStruct)*测试计数);

对于(int i=0;我不使用对象的
struct
。创建一个类以便获得良好的内存管理。然后还可以在它们所属的位置添加属性和方法。只对非Objective-C对象类型使用
struct
。@rmaddy我同意你的看法。相信我。但我想知道是否有办法使之成为可能。你不能使用stC结构中的指针。请参阅。@MartinR谢谢您的参考。没有办法解决这个问题吗?在为Astrings赋值时使用
\uu bridge\u retain
可以演示一下如何使用
objc\u retain(id值)来实现这一点吗
带有arc.h?正如在文章中指出的那样,您可以找到arc.h标题,通常它是不可见的,因此您需要将标题包含到您自己的项目中。注意:ivar必须在
@interface
中声明为
@public
,以便外部对象像这样访问它。@JamesSnook Right,删除
cfbrigingreetain(aObj);
肯定会崩溃。经过测试。非常感谢您的详细解释。有一个好的解释。如果您有一个常量字符串,它不会总是崩溃。例如,对象仍然存在于内存位置。有趣的是,没有任何泄漏。让我开始仔细查看您的答案。现在,+1。谢谢。