views:

172

answers:

2

Hi,

I have a WebView that I need to ask to load a website from a different class.Therefore I implemented the following function:

-(void)performResearch:(NSString *)aString {  
    NSLog(@"Received Request!");  
    [[researcher mainFrame]
    loadRequest:[NSURLRequest
    requestWithURL:[NSURL URLWithString:aString]]]; 
}

In my other class, I call the function like this:

Researcher *res = [[Researcher alloc] init];
[res performResearch:@"http://www.twitter.com"];
[res release];

I get no compiler errors and the NSLog does indeed get called, however the WebView doesn't load the webpage. No errors in the Log either.I'm puzzled.

Could anyone tell me what's wrong?

A: 

You don't show where researcher is declared, but it looks like a normal instance variable. Where does the value come from?

If it comes from outside the Researcher class, then it looks like it is nil because your other class is creating a new Researcher instance but not providing the researcher attribute.. If you pass messages to nil objects, the message is ignored. That is why you don't get an error. Try breaking the load request line out into several lines and log the values of the objects.

EDIT:

Interface Builder sets the UIWebView attribute of one particular instance of the Researcher class. To update that web view, you need to call performResearch on the same instance. You cannot use a new instance because it won't be connected to a web view at all.

If possible, you should pass the original Researcher object to the new class and use that instead:

[self.researcher performResearch:@"http://www.twitter.com"];
Colin Gislason
Researcher declared here: "@interface Researcher : NSObject {" in a file named Researcher.h. I want to access it via a different file.
David Schiefer
I mean this researcher in the `performResearcher` method: `[researcher mainFrame]`
Colin Gislason
IBOutlet WebView*researcher;
David Schiefer
I've updated my answer based on that.
Colin Gislason
How can I pass the original object to the new class? I have never done that before :/
David Schiefer
You have to find an object or method where the original object is available and you can pass it along down to the place where you create the new class. i.e. Your view controller may contain object A that creates object B that needs to call `performResearch`. You would need to pass the `Researcher` object down from the view controller to object A, which would pass it to object A. Object A could then use it.If this is impossible, a singleton might help (you can search stack overflow on how to do this).
Colin Gislason
I have fixed it by using "sharedInstance". It now works great! :-)
David Schiefer
+2  A: 
-(void)performResearch:(NSString *)aString {  
    NSLog(@"Received Request!");  
    [[researcher mainFrame]
    loadRequest:[NSURLRequest
    requestWithURL:[NSURL URLWithString:aString]]]; 
}

In my other class, I call the function like this:

Researcher *res = [[Researcher alloc] init];
[res performResearch:@"http://www.twitter.com"];
[res release];

Within performResearch:, the object you sent the performResearch: message to in the latter code is self. researcher is some other variable; you are talking to a different object that is probably not this Researcher.

In your comment on Colin Gislason's answer, you say that researcher is not a Researcher, but is a WebView. You would do well to correct this inaccurate choice of variable name.

Once you've renamed the variable to something more accurate, like webView, you then need to make sure there is something in it. Simply having a variable is of no help; you need to have a pointer to an object in the variable. Otherwise, the pointer in the variable is nil, and messages to nil do nothing at all. They do not crash, they do not fail, they do not succeed, they do not break—execution continues as if nothing happened, because it did.

You say that the variable is an IBOutlet; this implies that you mean to hook up the outlet in IB. One possible cause of your problem is that you forgot to do that, which would explain the variable containing nil. Make sure it's connected in IB.

The other possible cause of your problem is that this nib has not been loaded. If the Researcher object owns the nib, then it is generally its responsibility to load it, which means you need to do that. If some other object is loading a nib with both a Researcher and a WebView in it, then your creation of another Researcher object in the latter code snippet is wrong; this second Researcher object has no relation to the one in the nib, nor has it a WebView from any source. In this latter case, you would have to cut out the creation of a Researcher object, and use the one in the nib.

That last solution may require adding an outlet to the object whose class hosts the second code snippet. I disapprove of that solution. It's difficult to say what you should do because I'm not sure where Researcher objects fit in the MVC triumvirate. I suspect you need to think some more about which category it's in; I think that it should be a Controller, and that you will need to do some refactoring to re-establish the boundaries you should have between powers.

Failure to uphold MVC in your app generally results in Cocoa being harder to use than it normally is.

Peter Hosey
I think that the problem is that I am not using the same instance...I need to figure out now how to pass the original object to the new class...
David Schiefer
David Schiefer: See my second-to-last paragraph.
Peter Hosey