谁在处理程序文件上发布了我的对象?

时间:2010-07-27 22:20:46

标签: iphone objective-c ios4 objective-c++ objective-c-runtime

我是iphone开发界的新手..

我开始了一个新项目,我用它来测试我对Objective c的了解,它基本上从我的本地服务器发送和重新传输数据,然后,我将一些数据存储在类中,它工作正常。一切都在命令行上。

我的班级定义:

@interface MyClient : NSObject {

    NSString *name;

    NSMutableDictionary *in, *out;
}
-(BOOL) send;
-(BOOL) receive;

我设置了“out”值,将它们转换为xml并将它们发送到我的服务器。 我的服务器响应,我得到“in”值 名称是一个字符串,其中包含“in”值的一些特殊值。

问题来自于我尝试将我的代码与我在互联网上找到的一些示例/演示混合,演示带来了一些MVC? files(* Handler.h / m,* ViewController.h / m,* AppDelegate.h / m)。有一个按钮(btnStart),如果我按下那个按钮就会调用

- (IBAction) start: (id) sender;

如果我在start方法中放入send和receive调用,一切正常。

但是...

我尝试了两个按钮:发送和接收,两个工作(我已经尝试过它们并将输出发送到控制台),两种方法都是:

 1) - (IBAction) send: (id) sender;
 2) - (IBAction) receive: (id) sender;

内部* Handler.m

然后: 方法1)只执行[myClient send]; 方法2)只执行[myClient receive];

它不起作用,它抛出了一个“BAD_ACCESS”错误,我调试了(我使用了NSZombie ..)...

我发现当调用[myClient receive]

时,调用[myClient send]时存储的数据(in,out,name)被释放/ kill /不存在

我没有调用[myClient release]或类似的东西。

问题: 我究竟做错了什么? 该代码(方法1)和2))应该在哪里?

感谢。

更新: 这是一些代码,它是巨大的,所以我有复制&粘贴了有意义的部分,如果您需要更多代码请告诉我,谢谢!

// MyClass.h

@interface MyClient : NSObject {

    NSString *name;
    NSString *id;

    NSMutableDictionary *paramIn, *paramOut;
}
-(BOOL) send;
-(BOOL) receive;
-(void) setParam:(NSString *) key value: (NSString *) value;
-(NSString *) getParam:(NSString *) key;

//MyClass.m
#import "MyClass.h"
#import "TBXML.h"

@implementation MyClass
-(id) init {
    if ( !(self= [super init]) ){
        return nil;
    }

    paramIn=[[NSMutableDictionary alloc] init] ;
    paramOut=[[NSMutableDictionary alloc] init] ;

    return self;
} 

-(void) setParam:(NSString *) key value: (NSString *) value {
    [paramOut setObject:value   forKey:key];
}
-(NSString *) getParam:(NSString *) key {
    return [paramIn objectForKey:key];
}
-(BOOL) send{
    NSString *xml=[self getXML];
    // url conection ...
    // NSURLReq ...
    NSData *data= [ buffer  dataUsingEncoding: NSASCIIStringEncoding];
    TBXML * tbxml = [[TBXML tbxmlWithXMLData: data] retain];

    BOOL r=[self getXML: tbxml usingThisDictionary: &paramIn];

    if (r == YES) {
        name = [self getParam:@"nameResponse"];
        id =[self getParam:@"myId"];
    }
    [xml release];
    [data release];
    [tbxml release];

    return r;
}
-(BOOL) getXML:(TBXMLElement *)element usingThisDictionary:(NSMutableDictionary **) map {
    // search for each element...
    if (someError) return NO;

    [*map setObject: [TBXML attributeValue:attribute] forKey:[TBXML elementName:element]];

    return YES;
}
@end

更新: 谢谢你们(IwasRobbed,Simon,TechZen)

我一直在调试和更改代码......我发现: 为了保留名称和id值,我必须这样做:

name =[[self getParam:@"nameResponse"] copy];
id =[[self getParam:@"myId"] copy];

问题: Q1。在讨论旧代码(清除copy)时,nameid值已发布,因为

1)它被绑定到paramIn词典,paramId被释放了?

OR

2)这两个值都是从paramIn dictionay复制的,但是没有保留/复制指令

我想,答案是2),对吧?

Q2。我如何保留存储在NSMutableDictionaries paramInparamOut中的值?

感谢

2 个答案:

答案 0 :(得分:1)

如果您没有分配或保留有问题的对象(字符串?),并且是通过其他方法提供给您的,则可能是自动释放的。根据我的理解,该对象只保留到释放自动释放池(在当前运行循环结束时?)。这将导致在同一循环中调用send:receive:(当在同一函数中调用它们时),但是当单独调用时,将导致错误,因为该对象已被自动释放。

答案 1 :(得分:1)

您的实例变量nameinout未定义为属性,因此您必须对其保留进行微观管理。如果你没有,那么它们将无法存活超出你设置它们的方法的范围。

最简单的解决方案是为实例变量创建属性:

@property(nonatomic, retain)  NSString *name;
@property(nonatomic, retain)  NSMutableDictionary *in;
@property(nonatomic, retain)  NSMutableDictionary *out;

...然后使用自我符号,例如self.name访问它们。