如何在目标c中保留方法之外的数组

Posted

技术标签:

【中文标题】如何在目标c中保留方法之外的数组【英文标题】:how to preserve array outside of method in objective c 【发布时间】:2011-08-04 21:01:55 【问题描述】:

在 ASIFormDataRequest 之后,我从 JSON 创建一个临时 NSMutableArray *resultArray 然后将其添加到定义的 NSMutablearray *myData

-(void)viewDidLoad
    myData = [[NSMutableArray alloc] init];
    //request that calls gotInfo method


-(void)gotInfo:(ASIFormDataRequest *)request
    NSString *responseString = [request responseString];
    NSMutableArray *resultArray = [responseString yajl_JSON];
    [myData addObject:resultArray];


-(IBAction)doSomethingWithData:(id)sender
    //something with myData

但是当我尝试从 gotInfo: 方法之外调用 myData 时,我会遇到错误的访问错误,并且当我在方法之外检查 myData 时,它会显示 kern_protection_failure。所以我猜在方法之外, resultArray 显然被释放了,但它也从 myData 释放,因为 myData 中的对象共享相同的内存位置? 我也试过了

-(void)gotInfo:(ASIFormDataRequest *)request
    NSString *responseString = [request responseString];
    [myData addObject:[responseString yajl_JSON]];

如何保存 myData?

在我的头文件中:

#import <UIKit/UIKit.h>

@class ASIFormDataRequest;

@interface EventsTableController : UITableViewController <UITableViewDataSource>
    NSMutableArray *myData;

-(void)gotInfo:(ASIFormDataRequest *)request;

更新:

所以在 gbd 中,myData 被分配为 0x5e96560 所以我这样做了

po 0x5e96560

然后我得到 EXC_BAD_ACCESS,原因是地址为 KERN_PROTECTION_FAILURE:0x00000009

但如果我这样做了

po [[0x5e96560 objectAtIndex:0] objectForKey:@"key"]

然后我得到了价值!为什么yyyyy?

【问题讨论】:

可以把初始化myData的代码贴出来吗? @Saphrosit:我用代码更新了我的帖子 由于您将对象 [responseString yajl_JSON] 添加到数组 myData 中,因此数组 myData 会将对象的保留计数增加 1,因此它可能必须处理 yajl_JSON 方法。你确定它返回的是一个 NSMutableArray 指针吗? 是的,responseString来自json_encode($phpArray) 【参考方案1】:
@property(nonatomic,retain) NSMutableArray *myData 

并创建对象

self.myData = [[NSMutableArray alloc] init];

// and i assume your resultArray is a mature NSMutableArray object
[self.myData addObject:resultArray];

我能想到的使用复制的最佳方式是始终将 NSString 属性设置为“复制”而不是保留。这样,如果您搞砸并忘记释放物体所握住的绳子,您就可以从泄漏仪器中获得更准确的读数。文案的其他用途需要更仔细地考虑。

注意:您有责任在不使用该变量后释放 myData。

【讨论】:

我尝试了您的代码,但仍然出现同样的紧缩错误。我会仔细检查以确保 resultArray 没有问题 启用 NSDebugEnabled NSZombieEnabled MallocStackLogging MallocStackLoggingNoCompact 见42games.net/… _哪个会您更详细地了解错误_ 然后我们可以看到确切的问题是什么?在程序运行时,打开终端,执行 ps -ax 以查找进程的 pid,然后键入 leaks (pid) 以获取有关内存泄漏的一些信息你要走了。 我是否在 gdb 中键入 ps-ax 和泄漏(pid)? 如何访问终端? (对不起,我是新手) 我用泄漏 pid|more 检查了泄漏,显然我有 54 个……但我不认为内存泄漏会导致 kern 失败……我会尝试修复泄漏和看看有没有变化【参考方案2】:

当您将 myData 声明为 EventsTableController 内部的成员时,您实际上没有任何方法可以正确访问它,但是您没有为它设置 @property,也没有合成它。通过在您的 EventsTableController.m 文件中合成它,您告诉 xcode 生成正确触摸 myData 所需的 getter/setter,这就是您的程序似乎失败的地方。如果你这样做,这应该可以解决你的问题。

-卡罗利

【讨论】:

我认为只有当我的 EventsTableController 的实例是从另一个类创建时才使用 setter/getter。我添加了@property(nonatomic,copy) NSMutableArray *myData 并添加了合成,但我仍然得到内核保护失败 @Andrew Park:嗯,你在哪里初始化 myData?可能就是这样,虽然这通常会生成 EXC_BAD_ACCESS,但我还没有真正看到过紧缩保护失败。 您根本不需要任何用于 myData 的 getter 和 setter,除非您需要另一个类来访问该对象。 我在 viewDidLoad 中初始化了它,我用更多代码更新了我的帖子 很公平,我没有看到它提到他在哪里进行所有访问等,所以我想我会把它放进去。此时我不知道什么它可能是。【参考方案3】:

除了您的 ivar 的名称不同(mienVarmyVar),我看不出有什么问题。某些其他代码必须释放您的 ivar,或者您正在访问它之前 viewDidLoad 有机会实际创建数组(我敢打赌是后者)。

我认为您应该将代码放在 viewDidLoad 中的初始化方法中。不要忘记释放dealloc中的数组。

当然,您也可以编写自己的 myData getter 方法,进行延迟初始化,而不是在 init 方法中创建它:

- (NSMutableArray *) myData

    if (!myData)
        myData = [[NSMutableArray alloc] init];
    return myData;

请注意,现在,您应该访问 self.myData 如果您想使用它。

【讨论】:

我更新了我的代码,因为我意识到事件的流程并不清楚。所以 gotInfo: 方法在 viewDidLoad 之后运行,我在方法的末尾放置了一个断点,并查看 myData 中的对象。然后我设置了一个需要 myData 的带有 IBAction 的按钮,但是当我将断点放在 IBAction 中时,但现在出现了 kern 失败 如果无法访问您的其余代码,很难判断哪些其他代码会使您的数组无效,抱歉。 我明白了,只有一个问题。 addObject 之后,即使临时数组被释放,myData 还是应该保留它? 应该,除非它是“过度发布”,即发布两次。 当你将断点放在 IBAction 中时,就会出现 kern 失败。它是否在控制台中详细说明了该错误。您确定您为按钮提供了正确的操作引用吗?【参考方案4】:

我认为 NSString yajl_JSON 类别可以返回一个数组或字典 - 您可能需要检查下一行结果数组的类型,因为它可能是一个 NSDictionary:

NSMutableArray *resultArray = [responseString yajl_JSON];

如果您将它视为一个数组,而它可能会导致您的问题。

(下面NSObject+YAJL类的相关代码)

YAJLDocument *document = [[YAJLDocument alloc] initWithData:data parserOptions:options error:error];
id root = [document.root retain];
[document release];
return [root autorelease];

(在 YAJLDocument 对象中)

@interface YAJLDocument : NSObject <YAJLParserDelegate> 
(id root_; // NSArray or NSDictionary

【讨论】:

我尝试将[responseString yajl_JSON] 保存为 NSMutableArray 和 NSMutableDictionary 但两者都不起作用。如此令人沮丧的错误

以上是关于如何在目标c中保留方法之外的数组的主要内容,如果未能解决你的问题,请参考以下文章

如何更改指针变量的值并将更改保留在函数之外而无需通过引用传递?

目标 C NSString 保留

如何强制 Python 将整数保留在科学记数法之外

目标 C - 因保留周期而丢失

如何在目标c中动态创建无符号字符类型数组

如何对数组进行排序但保留C中重复元素的位置?