我已将按钮链接到以下方法:
- (IBAction)searchButton
{
NSString *searchText = _searchField.text;
NSLog(@"lol");
[_search testSearch:searchText];
}
最后一行在名为search的对象中调用方法testSearch,定义如下:
@property (strong, nonatomic) Search *search;
在Search中,testSearch的定义如下:
-(void)testSearch:(NSString *)testString
{
NSLog(@"HELLO");
}
当我点击搜索时,我的最终输出只是“lol”(每次我点击按钮)。它不打印“HELLO”,因为testSearch应该这样做。我在Search.h中包含了testSearch,所以它应该是可访问的...为什么不调用这个方法?
答案 0 :(得分:6)
您应首先将_search
ivar初始化为指定初始化程序中的Search
实例(或viewDidLoad
或其他“用户”将使用此方法)。
- init {
if ((self = [super init])) {
_search = [[Search alloc] init];
}
return self;
}
由于各种原因,你应该通常避免在getter方法中进行延迟初始化:
它增加了不必要的代码;使用@property
和默认的综合实现。导致更简单的代码而不是更少。
执行延迟初始化的getter会产生一个导致变异的getter。这是不一致的,当调用getter 时看到KVO更改通知是很奇怪的(当然,除非您不触发KVO通知...此时,您不可观察突变)。
导致突变的getter本质上不是线程安全的,除非你添加代码,棘手的代码,以实现它。
延迟初始化通常是不成熟的优化。除非由于“太快”初始化资源而导致可识别内存或CPU性能问题,否则添加延迟初始化的复杂性是浪费精力。
延迟初始化可能导致奇怪的排序依赖性和其他复杂性。最好有一个已知的初始化子系统的入口点,而不是依赖于在Y之前初始化子系统X,这都是副作用。
答案 1 :(得分:0)
您要发送邮件的搜索对象尚未实例化,因此您要向nil发送邮件。在Obj-C中,这不会使程序崩溃,而是什么都不做。它是Objective-C编程中的最佳实践,用于在iVar的getter方法中执行延迟实例化。此外,您必须将此最佳实践与不直接访问iVars相结合,并在您尝试访问的任何iVar上使用setter和getter。下面是您的搜索iVar的getter方法中的延迟实例化示例:
-(Search *)search
{
if(!_search){
_search = [[Search alloc]init];
}
return _search;
}
这是您在不直接访问iVar时的方法调用:
[search testSearch:searchText];