我正在为UIToolbar创建子类,因为我将在我的应用程序中重复使用它。 UIToolbar使用委托协议:
//
// UIToolbarCustom.h
//
#import <UIKit/UIKit.h>
@protocol UIToolbarCustomDelegate
@required
- (void)tab:(UIBarButtonItem *)sender;
- (void)ok:(UIBarButtonItem *)sender;
@end
@interface UIToolbarCustom : UIToolbar {
id <UIToolbarCustomDelegate> delegate;
}
@property (strong, nonatomic) id delegate;
@end
Standford iOS开发课程老师建议明确声明所有带有下划线的ivars前缀,如:
@implementation UIToolbarCustom
@synthesize delegate = _delegate;
@end
但是,在这个指定scenarion中它给了我一个错误:
error: property 'delegate' attempting to use ivar '_delegate'...
如果我使用以下代码就可以了:
@synthesize delegate = __delegate; or
@synthesize delegate;
这里发生了什么? UIToolbar类中是否有一个名为_delegate的私有实例变量?
更新
感谢所有人的澄清和说明,我学到了很多东西。事实证明我是iOS开发的新手(这是我的第一个应用程序第二版,所以我试图正确地做= p)。按照提示,我推出了这个新的头文件:
//
// Toolbar.h
//
#import <UIKit/UIKit.h>
@protocol ToolbarDelegate
@required
- (void)tab:(UIBarButtonItem *)sender;
- (void)ok:(UIBarButtonItem *)sender;
@end
@interface Toolbar : UIToolbar
@property (strong, nonatomic) id delegate;
@end
注意:
删除了类前缀。
删除了委托声明(我使用的是ios委托教程代码,但代码示例使用较旧的xcode版本,需要声明)。
合成被删除,我也不知道我们不再需要合成我们的属性了。
答案 0 :(得分:5)
这里发生了什么? UIToolbar类中是否有一个名为_delegate的私有实例变量?
是的,这正是问题所在。您需要为实例变量提供不同的名称。 __delegate
可以使用,或者您可以在名称前加上3个字母的前缀(参见最后一段)。
请注意,您已将ivar声明为delegate
,然后在synthesize语句中告诉编译器使用_delegate
。实际上,这意味着您的delegate
ivar根本没有被使用。无论如何,如果您正在为iOS编写(而不是32位Mac),就像您一样,在子类的@interface部分中不需要显式的实例变量声明,因为编译器会自动为它创建它你。
最后,将自己的子类命名为以'UI'开头的东西是不好的形式,因为UI前缀是为属于UIKit的类保留的。您应该使用自己的3个字母前缀,否则根本没有前缀。问题是UIKit的未来版本可能包含一个名为“UIToolbarCustom”的类,您的子类将与它发生碰撞。
答案 1 :(得分:1)
从去年开始,当Xcode 4.3问世时,您无需合成您的属性。它由编译器为您完成(生成一个ivar,并在其名称中添加一个前导下划线)。这意味着您也不需要声明ivar。如果您这样做,请务必将其命名为_delegate
以外的其他内容。
所以,你真正需要的就是这一行:
@property (strong, nonatomic) id<UIToolbarCustomDelegate> delegate;
更新:有关完整报道,请参阅Andrew Madsen's answer。原来UIToolbar有自己的名为_delegate
的ivar。谁知道!