与伊娃问题

时间:2013-01-07 21:42:00

标签: ios cocoa-touch

我正在为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

注意:

  1. 删除了类前缀。

  2. 删除了委托声明(我使用的是ios委托教程代码,但代码示例使用较旧的xcode版本,需要声明)。

  3. 合成被删除,我也不知道我们不再需要合成我们的属性了。

  4. PS:显然代码不起作用,因为ivar问题。我要更改它的名字,所以我不需要合成它,也不确定要使用什么名称......

2 个答案:

答案 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。谁知道!