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。谢谢。