【问题标题】:how to preserve array outside of method in objective c如何在目标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)

标签: iphone objective-c arrays release


【解决方案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 MallocStackLoggingNoCompact42games.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 但两者都不起作用。如此令人沮丧的错误
猜你喜欢
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多