【问题标题】:Objective C: Passing NSDictionary from One Class to Another目标 C:将 NSDictionary 从一个类传递到另一个类
【发布时间】:2011-07-07 19:49:28
【问题描述】:

全部,

免责声明:我知道还有其他问题会提出类似的问题,但没有一个提供我理解的答案或适用于我的情况的答案。

我有两个班级,classA 和 classB。在 classA 中有一个创建 NSMutableDictionary 的 void 实例方法(如果您需要详细信息,它是一个 XMLparser)。在 classA 的 XMLParser 运行并创建和填充 NSMutableDictionary 之后,调用 classB 需要对该字典执行一些其他操作。由于某种原因,classB 无法访问 classA 中的 NSMutableDictionary(实际上,它可以访问它,但由于某种原因它显示为“NULL”)。我该怎么办?

提前致谢。

编辑:你要求源代码,你得到了。 ClassA 下面,有问题的字典称为“响应”。

#import "XMLParser.h"
#import "CardSetupViewController.h"

@implementation XMLParser

@synthesize response;

- (XMLParser *) initXMLParser
{
    self = [super init];
    // init dictionary of response data 
    response = [[NSMutableDictionary alloc] init];
    return self;
}

//Gets Start Element of SessionData
- (void)parser:(NSXMLParser *)parser 
        didStartElement:(NSString *)elementName 
        namespaceURI:(NSString *)namespaceURI 
        qualifiedName:(NSString *)qualifiedName 
        attributes:(NSDictionary *)attributeDict 
{

    if ([elementName isEqualToString:@"SessionData"]) 
    {
        NSLog(@"Found SessionData in the return XML! Continuing...");
        //response is a NSMutableArray instance variable

        //THIS SHOULD NEVER NEED TO BE USED
            if (!response)//if array is empty, it makes it!
            {
                NSLog(@"Dictionary is empty for some reason, creating...");
            response = [[NSMutableDictionary alloc] init];
            }
        //END: THIS SHOULD NEVER BE USED
        return;
    }
    else
    {
        currentElementName = elementName;
        NSLog(@"Current Element Name = %@", currentElementName);
        return;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{
    if (!currentElementValue) {
        // init the ad hoc string with the value     
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        [currentElementValue setString:string];
        NSLog(@"Processing value for : %@", string);
    }
}  

//Gets End Element of SessionData
- (void)parser:(NSXMLParser *)parser 
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"SessionData"]) 
    {
        // We reached the end of the XML document
        // dumps dictionary into log
        NSLog(@"Dump:%@", [response description]);
        return;
    }
    else
    {
        //Adds key and object to dictionary
        [response setObject:currentElementValue forKey:currentElementName];
        NSLog(@"Set values, going around again... brb.");
    }
    currentElementValue = nil;
    currentElementName = nil;
}


@end

【问题讨论】:

  • 相信你把与你的问题相关的源码贴出来会得到更好的帮助
  • 我已附上源代码。谢谢!
  • 在您尝试在 B 上使用它之前,确保没有释放 classA 或释放您的字典。另外,是否涉及任何线程?
  • 附带说明,您的初始化程序不遵循约定。它的返回类型应为id,如Implementing an Initializer 中所述。它还应该检查if (self),如Handling Initialization Failure中所述
  • 创建这个 ClassA 的实例,然后创建 ClassB 的实例,然后将此响应从一个传递到另一个的代码呢?这不是你遇到问题的地方吗?

标签: iphone objective-c xcode


【解决方案1】:

【讨论】:

【解决方案2】:

是 currentElementName 和 currentElementValue ivars 吗?如果是这样,每次您捕获一个元素或一个值时,您都必须释放您的 ivar 并保留您捕获的新值。

此外,正如 cmets 所说,您没有遵循任何有关编写正确初始化程序的规则。

classB 呢?是不是有一些逻辑可以让你的字典被释放? 尝试管理更多内存。

【讨论】:

  • 使用 ARC。由于 NDA,不会进入 ARC,但内存管理应该很好。
【解决方案3】:

你有几个选择......实际上有很多选择

选项 A:(设置)

@interface ClassB{
NSDictionary * someDict;
}
-(void)setSomeDict:(NSDictionary *)aDict;
@end

@implementation ClassB
-(void)setSomeDict:(NSDictionary *)aDict
{
   someDict = [aDict retain];//or copy depending on your needs;
}

@end

somewhere in ClassA...

ClassB * b = [ClassB new];
[b setSomeDict: someOtherDict];

选项 B:(推)

@interface ClassB{
NSDictionary * someDict;
}
-(void)doSomethingWithDict:(NSDictionary *)aDict;
@end

@implementation ClassB
-(void)doSomethingWithDict:(NSDictionary *)aDict
{
   NSLog(@"did something with aDict: %@",aDict);
}

@end

somewhere in ClassA...

ClassB * b = [ClassB new];
[b doSomethingWithDict: someOtherDict];

选项 c:(init)

@interface ClassB{
NSDictionary * someDict;
}
-(id)initWithDict:(NSDictionary *)aDict;
@end

@implementation ClassB
-(id)initWithDict:(NSDictionary *)aDict
{
   self = [super init];
   if(self)
   {
        someDict = [someDict retain]; //or copy depending on your needs
   }
   NSLog(@"did something with aDict: %@",aDict);
}

@end

somewhere in ClassA...

ClassB * b = [[ClassB alloc] initWithDict:someOtherDict];
[b doSomethingelse];

您还可以使用属性等...有很多选项,但您也应该了解对象所有权,以免最终泄露字典。

-(void)dealloc
{
    [someDict release];
}

应该添加到classB中。

【讨论】:

    【解决方案4】:

    首先检查你是否在 NSXMLParser 的这个委托方法中得到响应

    - (void)parserDidEndDocument:(NSXMLParser *)parser;
    

    并通过委托(您应该在此类中实现)发送响应,委托方法将在另一个类中实现...简单!!!

    【讨论】:

      猜你喜欢
      • 2016-10-03
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      相关资源
      最近更新 更多