I'm creating a simple project for iPhone, using Xcode and Interface Builder. While I understand what a delegate is, I have a problem with using it.
我正在使用Xcode和Interface Builder为iPhone创建一个简单的项目。虽然我理解委托是什么,但我在使用它时遇到了问题。
I have an UITextField in my interface. It displays keyboard when user taps on it, but I need to program manually how to hide keyboard. It can be done using delegates. So in IB, I'm taking Object from library, giving it's class name as Control1Delegate and then connecting the delegate outlet from my textfield to be this Control1Delegate. I also have .m and .h files for this Control1Delegate class :
我的界面中有一个UITextField。当用户点击键盘时它会显示键盘,但我需要手动编程如何隐藏键盘。可以使用代表完成。所以在IB中,我从库中获取Object,将其类名称作为Control1Delegate,然后将我的textfield中的委托出口连接为此Control1Delegate。我还有这个Control1Delegate类的.m和.h文件:
Control1Delegate.h
@interface Control1Delegate : NSObject <UITextFieldDelegate> {
}
- (BOOL) textFieldShouldReturn:(UITextField *)textField;
@end
Control1Delegate.m
#import "Control1Delegate.h"
@implementation Control1Delegate
- (BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
@end
But this doesn't work. When running, it just never reaches the textFieldShouldReturn method or crashes without msg or with EXEC_BAD_ACCESS. The funny thing is that when I move the method into controller file (the one wizard has generated) and connect from UITextField to this controller (File's Owner), everything works as expected. I saw that most apple code tutorial puts delegated methods into random objects rather then separate class - I would like to know why. Can't I have delegate in separate class?
但这不起作用。运行时,它永远不会到达textFieldShouldReturn方法或没有msg或EXEC_BAD_ACCESS崩溃。有趣的是,当我将方法移动到控制器文件(一个向导生成)并从UITextField连接到此控制器(文件的所有者)时,一切都按预期工作。我看到大多数苹果代码教程将委托方法放入随机对象而不是单独的类 - 我想知道原因。我不能在单独的课上有代表吗?
What I'm missing here? Some null pointer? Object livecycle?
我在这里缺少什么?一些空指针?对象生命周期?
3 个解决方案
#1
Your Control1Delegate object is getting destroyed soon after it is created. All top-level Nib objects must be retained if you want to keep them alive. Refer to the Resource Programming Guide: The Nib Object Life Cycle.
您的Control1Delegate对象在创建后很快就会被销毁。如果要保持活动状态,则必须保留所有*Nib对象。请参阅资源编程指南:Nib对象生命周期。
The File's Owner could have a property like this, in order to retain the object:
文件的所有者可以拥有这样的属性,以保留对象:
@property (nonatomic, retain) IBOutlet Control1Delegate *control1delegate;
Remember to release the object after it is no longer needed.
请记住在不再需要后释放该对象。
#2
You can put delegate methods in any class, including one built just for that purpose. The reason Apple (and other programmers) usually don't make classes specifically for delegate functions is it becomes overly complex and hard to share data. For instance, in one of my projects I might make a Window Controller subclass that handles delegate methods from the window, the table view inside the window, and the window's toolbar. Everything you need to manipulate and maintain the state of that window is in one controller class. Now imagine three separate classes (plus probably a controller class to manage them) doing the same functions-- that's a lot of extra work for no real benefit.
您可以将委托方法放在任何类中,包括仅为此目的而构建的方法。 Apple(和其他程序员)通常不会专门为委托功能创建类的原因是它变得过于复杂并且难以共享数据。例如,在我的一个项目中,我可能会创建一个Window Controller子类,用于处理窗口中的委托方法,窗口内的表视图和窗口的工具栏。操作和维护该窗口状态所需的一切都在一个控制器类中。现在想象一下三个独立的类(加上可能是一个管理它们的控制器类)执行相同的功能 - 这是很多额外的工作,没有真正的好处。
As to why it's crashing, it sounds like you're making a mistake with memory management somewhere else in your application. You can use the debugger to track down exactly where it's coming from.
至于为什么它会崩溃,听起来你在应用程序的其他地方的内存管理上犯了一个错误。您可以使用调试器准确跟踪它的来源。
#3
Thank you both. Not only I know now how to solve my problem, but also finally understood how objects are retained in Nib creation process. It's not enough to create object in IB, if it's a new entity, it has to be connected to a real ivar in File's Owner (with properly synthetised getter/setter).
谢谢你们俩。我现在不仅知道如何解决我的问题,而且最终了解了如何在Nib创建过程中保留对象。在IB中创建对象是不够的,如果它是一个新实体,它必须连接到文件所有者中的真实ivar(具有适当合成的getter / setter)。
#1
Your Control1Delegate object is getting destroyed soon after it is created. All top-level Nib objects must be retained if you want to keep them alive. Refer to the Resource Programming Guide: The Nib Object Life Cycle.
您的Control1Delegate对象在创建后很快就会被销毁。如果要保持活动状态,则必须保留所有*Nib对象。请参阅资源编程指南:Nib对象生命周期。
The File's Owner could have a property like this, in order to retain the object:
文件的所有者可以拥有这样的属性,以保留对象:
@property (nonatomic, retain) IBOutlet Control1Delegate *control1delegate;
Remember to release the object after it is no longer needed.
请记住在不再需要后释放该对象。
#2
You can put delegate methods in any class, including one built just for that purpose. The reason Apple (and other programmers) usually don't make classes specifically for delegate functions is it becomes overly complex and hard to share data. For instance, in one of my projects I might make a Window Controller subclass that handles delegate methods from the window, the table view inside the window, and the window's toolbar. Everything you need to manipulate and maintain the state of that window is in one controller class. Now imagine three separate classes (plus probably a controller class to manage them) doing the same functions-- that's a lot of extra work for no real benefit.
您可以将委托方法放在任何类中,包括仅为此目的而构建的方法。 Apple(和其他程序员)通常不会专门为委托功能创建类的原因是它变得过于复杂并且难以共享数据。例如,在我的一个项目中,我可能会创建一个Window Controller子类,用于处理窗口中的委托方法,窗口内的表视图和窗口的工具栏。操作和维护该窗口状态所需的一切都在一个控制器类中。现在想象一下三个独立的类(加上可能是一个管理它们的控制器类)执行相同的功能 - 这是很多额外的工作,没有真正的好处。
As to why it's crashing, it sounds like you're making a mistake with memory management somewhere else in your application. You can use the debugger to track down exactly where it's coming from.
至于为什么它会崩溃,听起来你在应用程序的其他地方的内存管理上犯了一个错误。您可以使用调试器准确跟踪它的来源。
#3
Thank you both. Not only I know now how to solve my problem, but also finally understood how objects are retained in Nib creation process. It's not enough to create object in IB, if it's a new entity, it has to be connected to a real ivar in File's Owner (with properly synthetised getter/setter).
谢谢你们俩。我现在不仅知道如何解决我的问题,而且最终了解了如何在Nib创建过程中保留对象。在IB中创建对象是不够的,如果它是一个新实体,它必须连接到文件所有者中的真实ivar(具有适当合成的getter / setter)。