开发者

Confused why one piece of code works and another doesn't in Objective C

开发者 https://www.devze.com 2023-01-20 02:53 出处:网络
Sorry about the title being extremely vague, I\'m new to Objective C and struggling a little with it. Basically I have the following section of code:

Sorry about the title being extremely vague, I'm new to Objective C and struggling a little with it. Basically I have the following section of code:

Graph *graph1 = [[Graph alloc] init];
[graph1 addNode:@"TEST"];

which is working to a degree. But I want to change it because the above code happens on a button press, and therefore I assume I am creating a new "*graph1" every time I do this. I thought I could simply change it to this:

if(self = [super init]) 
{
    [self setGraph: [[Graph alloc] init]];
}
return self;

Where the above is in the init method, and below is the modified function:

[graph addNode:@"TEST"];

However when debugging I've found addNode method is never called when it's like this.

Thanks Zac

This is testViewController.h

#import <UIKit/UIKit.h>
@class Graph;
@class Node;

@interface testViewController : UIViewController {

    Graph       *graph;
    UILabel     *label;

}


@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) Graph *graph;

- (IBAction) buttonPressed:(id)sender;

@end

This is textViewController.m

#import "testViewController.h"
#import "Graph.h"
@implementation testViewController

@synthesize  label, graph;

- (id)init
{
    if(self = [super init]) 
    {
        [self setGraph: [[Graph alloc] init]];
    }
    return self;
}

- (IBAction)buttonPressed:(id)sender
{
    //Graph *graph1 = [[Graph alloc] init];
  开发者_JAVA技巧  [graph addNode:@"TEST"];


    Node *node1 = [[Node alloc] initWithLabel: @"LABEL"];
    label.text = node1.label;
}


The first thing that comes to mind is that graph is nil and thus invoking a method (sending a message) to it will result in nothing. An unwanted release will cause an EXC_BAD_ACCESS, and this seems to be not the case.

I suppose you are calling all of this in a UIViewController subclass, right? Are you sure the right init is called? If you are using a NIB you should override the -(id)initWithNibName:bundle: and place you code there. I guess the code is probably in the plain -(id)init, since you are calling [super init] and not [super initWithNibName:nameOrNil bundle:bundleOrNil], but this way, if initialize the controller with the NIB you custom code is never called and thus graph is nil.

By the way, if the graph property is (retain) you are also causing a memory leak in the init.


I'm sure you're through this problem now, but I agree that the reason "add" is "not being called" is that your graph object is nil at that moment

I'd say, first put a test message around your "addNode" call

 NSLog(@"We tried to add here");
[graph addNode:@"TEST"];

That will show you that the add is being called -- I bet it is.

Then, where you had your previous call to initialize "graph" right before your add call, try conditionally initializing it:

 if(graph == nil) graph = [[Graph alloc] init];
[graph addNode:@"TEST"];

Note, this is all just to find the problem. Finally I'd say you have some challenges in here with how you are dealing with memory. You may not have reference issues, but later leaks. And depending upon how often this code is executed it could be an issue.

But at least you may get to your issue easier with the above tests.


Have you declared the graph variable in the header? ie: Graph *graph; and the corresponding @property (nonatomic, retain) Graph *graph;

Then I would do this:

   -(id) init {
        graph = [[Graph alloc] init];
        [graph retain];
    }

that might help (the only reason I think it wouldn't would be because a) if your variable wasn't declared then you would get a warning like graph may not respond to addNode and if it wasn't retained then your app would crash when it runs)... other than that, I can't see what would be the problem. If that doesn't work, can you please post all your code from your .h and .m files?


Then I would do this:

-(id) init {
        graph = [[Graph alloc] init];
        [graph retain];
    }

that might help

This would result in a memory leak. The retain count of the object pointed to by graph will have a retain count of 2. Not ideal. If you declare the property with the retain attribute then

[self setGraph:[[[Graph alloc] init] autorelease]];

should do it. I go with -

self.graph = [[[Graph alloc] init] autorelease];

There could be many reasons the addNode: method is not being called. Put break points in the enclosing method and see if everything is working as you expect it to.

0

精彩评论

暂无评论...
验证码 换一张
取 消