Reputation: 12684
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
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
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