muttley91
muttley91

Reputation: 12684

Method is not being called

I've linked a button to the following method:

- (IBAction)searchButton
{
    NSString *searchText = _searchField.text;
    NSLog(@"lol");
    [_search testSearch:searchText];
}

The last line calls the method testSearch within an object named search, defined as follows:

@property (strong, nonatomic) Search *search;

Within Search, testSearch is defined as follows:

-(void)testSearch:(NSString *)testString
{
    NSLog(@"HELLO");
}

My final output, when I click search, is only "lol" (each time I click the button). It does NOT print "HELLO", as testSearch should be doing. I have included testSearch in Search.h, so it should be accessible...why isn't this method being called?

Upvotes: 0

Views: 218

Answers (2)

bbum
bbum

Reputation: 162722

You should start by initializing your _search ivar to an instance of Search in your designated initializer (or in viewDidLoad or some other "user gonna use this" method).

- init {
   if ((self = [super init])) {
       _search = [[Search alloc] init];
   }
   return self;
}

You should generally avoid lazy initialization in getter methods for a variety of reasons:

  • It adds unnecessary code; use @property and the default synthesized implementations. Leads to simpler code and less of it.

  • a getter that does lazy initialization yields a getter that causes mutation. That is inconsistent it is quite odd to see a KVO change notification when calling a getter (unless, of course, you don't fire the KVO notification... at which point, you have non-observeable mutation).

  • a getter that causes mutation is inherently not thread safe unless you add the code, tricky code, to make it so.

  • lazy initialization is generally a premature optimization. Unless you have an identifiable memory or CPU performance issue caused by initializing a resource "too soon", then adding the complexity of lazy initialization is wasted effort.

  • lazy initialization can lead to weird ordering dependencies and other complexities. Far better to have a known entry point for initializing a subsystem than to rely on subsystem X being initialized prior to Y, both by side effect.

Upvotes: 6

drD
drD

Reputation: 21

The search object you are sending the message to has not been instantiated so you are sending a message to nil. In Obj-C this does not crash the program, instead it does nothing. Its a best practice in Objective-C programming to perform lazy instantiation in the getter method of the iVar. Additionally, you would have to couple this best practice with not accessing your iVars directly and use the setters and getters for whichever iVar you are trying to access. Below is an example of lazy instantiation in the getter method for your search iVar:

-(Search *)search
{
     if(!_search){
        _search = [[Search alloc]init];
     }
     return _search;
}

Here is your method call while NOT accessing the iVar directly:

[search testSearch:searchText];

Upvotes: 0

Related Questions