ViewController 实现 UITextFieldDelegate 时出错
Posted
技术标签:
【中文标题】ViewController 实现 UITextFieldDelegate 时出错【英文标题】:Error when ViewController is implementing UITextFieldDelegate 【发布时间】:2011-06-25 19:22:36 【问题描述】:在我的 ViewController 类中实现 UITextFieldDelegate 时,在文本字段中输入第一个字符时会引发以下错误:
-[MyViewController respondsToSelector:]: message sent to deallocated instance...
所以,我尝试创建一个单独的类(仅继承 NSObject)并实现 UITextFieldDelegate。你猜怎么着,效果很好。但是,这引入了一些其他问题,因为我必须做很多我想避免的丑陋的跨类通信。这是我的应用委托代码的相关部分:
@interface RMSAppDelegate : NSObject <UIApplicationDelegate,
UITabBarControllerDelegate>
@property (nonatomic, retain) UIViewController* myViewController;
@end
@implementation MyAppDelegate
@synthesize myViewController;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
myViewController = [[MyViewController alloc]
initWithNibName:@"MyView" bundle:nil];
[self.window setRootViewController:myViewController];
[self.window makeKeyAndVisible];
return YES;
@end
.. 这是正在显示的内容:
@interface MyViewController : UIViewController <UITextFieldDelegate>
@property (nonatomic, retain) IBOutlet UITextField* pinTextField;
- (void)viewDidLoad;
@end
@implementation MyViewController
@synthesize pinTextField;
- (void)viewDidLoad
// DOES NOT WORK (WHY?)
//[pinTextField setDelegate:self];
// WORKS, BUT I'D LIKE TO AVOID
[pinTextField setDelegate:[[[MyTextFieldDelegate alloc] init] autorelease];
[pinTextField becomeFirstResponder];
[super viewDidLoad];
@end
如果您看到任何我可以做得更好的代码(甚至是离题),请发表评论。
【问题讨论】:
@albertamg:谢谢,我已将代码修改为示例,但遗漏了一些内容。去掉dealloc
方法,缩短代码,专注问题
【参考方案1】:
由于您要求提供题外话代码 cmets:您忘记致电 [super viewDidLoad]
。您也不需要重新声明原型来覆盖它。 @synthesize textFieldDelegate
无效,因为您在名为 textFieldDelegate
的类中没有属性。而你的 dealloc
方法正在释放一个名为 tfd
的 ivar,它似乎实际上并不存在于类中。
您真正的问题是您在分配视图控制器的任何时候都没有正确保留它。可能是视图控制器在 nib 中被实例化并与 ivar 关联,而不是声明为 retain
的属性,或者没有与任何东西关联。或者可能是您在代码中分配它,将其视图添加为某事物的子视图,然后在不保留视图控制器本身的情况下释放它。或者可能只是你在不应该发布的时候发布了它。
您的其他类特别有效,因为您正在泄漏对象,因此它永远不会被释放。如果您采用这种方法,更好的解决方案是在分配对象时将其存储在 ivar 中,然后在 dealloc
和 viewDidUnload
中释放它(并将 ivar 设置为 nil)。
【讨论】:
较新版本的编译器将使用@synthesize
生成您的实例变量:@synthesize foo = _foo;
将使用下划线名称创建 ivar(从风格上建议,以免新编码人员混淆他们正在访问的内容)
同意,您在提供的代码范围之外未充分保留 MyViewController 的实例
我已经更新了我的代码并将 UIVC 的 init 添加到我的问题中。请查阅! @synthesize
不需要多余的 ivar 声明,因为 bshirley
声明
这只是一点点帮助。当然它“可能是我在不应该发布的时候发布了一些东西”......但这不总是message sent to deallocated instance
在对象上的原因吗?无论如何,我现在已经发布了更多代码,所以看看 :)
@Simeon:你会惊讶地发现人们经常需要被告知这一点。您更新的代码工作正常。很明显,您正在尝试减少代码以仅显示错误,但是当您这样做时,您需要确保减少的代码仍然显示错误。【参考方案2】:
好的,我终于自己解决了这个问题。我没有更改代码。我的 NIB (.xib) 是罪魁祸首!
我认为嵌套的 UIViewControllers 是可以的,我仍然认为它们在某些情况下是可以的(并且可能使用另一种编程方法)。无论如何,我正在用一个 NIB 初始化我的类 MyViewController
,它在 Objects 面板中有一个 UIViewController 作为第一个对象。
我通过将 UIView 作为“对象”面板中的第一个对象并将文件的所有者设置为 UIViewController 来解决此问题。
代码正确,NIB 错误。感谢您的帮助。
【讨论】:
以上是关于ViewController 实现 UITextFieldDelegate 时出错的主要内容,如果未能解决你的问题,请参考以下文章
ViewController 实现 UITextFieldDelegate 时出错
实现从 viewController 到 DataManager 类的委托
dealloc 方法从 Xcode 4 中的 ViewController 实现文件模板中消失了吗?