Ios ivar问题
我正在对UIToolbar进行子类化,因为我将在我的应用程序中重复使用它。UIToolbar使用委托协议:Ios ivar问题,ios,cocoa-touch,Ios,Cocoa Touch,我正在对UIToolbar进行子类化,因为我将在我的应用程序中重复使用它。UIToolbar使用委托协议: // // UIToolbarCustom.h // #import <UIKit/UIKit.h> @protocol UIToolbarCustomDelegate @required - (void)tab:(UIBarButtonItem *)sender; - (void)ok:(UIBarButtonItem *)sender; @end @interfa
//
// 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
但是,在这个场景中,它给了我一个错误:
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
//
//工具栏.h
//
#进口
@协议工具栏委托
@必需的
-(无效)选项卡:(UIBarButtonItem*)发送方;
-(无效)ok:(UIBarButtonItem*)发送方;
@结束
@界面工具栏:UIToolbar
@属性(强,非原子)id委托;
@结束
注:
委托
,然后在synthesis语句中告诉编译器使用\u委托
。实际上,这意味着您的代理ivar根本没有被使用。在任何情况下,如果您正在为iOS编写(与32位Mac相反),就像您一样,您不需要在子类的@interface部分中声明显式实例变量,因为编译器将自动为您创建它
最后,将自己的子类命名为以“UI”开头是不好的,因为UI前缀是为属于UIKit的类保留的。你应该使用你自己的3个字母的前缀,否则就没有前缀了。问题是未来版本的UIKit可能会包含一个名为“UIToolbarCustom”的类,而您的子类会与之发生冲突。自从去年Xcode 4.3问世以来,您不需要合成属性。它由编译器为您完成(生成一个ivar,并在其名称中添加一个前导下划线)。这意味着您也不需要声明ivar。如果这样做,请确保将其命名为\u delegate
以外的名称
所以,您真正需要的是这一行:
@property (strong, nonatomic) id<UIToolbarCustomDelegate> delegate;
@property(强,非原子)id委托;
更新:有关完整故事,请参阅。原来UIToolbar有自己的ivar,名为\u delegate
。谁知道呢 这是正确的,但是编译器将合成一个名为\u delegate
的实例变量,并且它将发生同样的冲突。正确。但我想你不需要申报这个ivar。我更新了我的答案,以便更好地解释这一点。作为一种解决方案,这是可行的,但它并没有向询问者完全解释为什么他的代码不起作用-原因是,他声明了一个ivar和一个同名属性。@BlackRider,你说得对,你不需要显式声明实例变量。但这与子类的ivar名称与其中一个超类ivar冲突无关。如果省略ivar声明,@synthesis delegate=\u delegate
仍然会创建一个名为\u delegate
的ivar(正如它在OP发布的代码中实际所做的那样,因为他声明的ivar名为delegate
),并且它仍然会与名为同一事物的超类的ivar发生冲突。@AndrewMadsen:刚刚看到了你的答案,这很有意义。谢谢你的解释!这并不完全正确。。。他是在与自己之前的声明相冲突,而不是私有/内部苹果ivar(因为它们使用不同的ivar约定,所以不会发生冲突)。同样,这不是真的。而且,如果您不认为可以与私有/内部Apple ivar冲突,请尝试将UIViewController子类化,并创建一个名为popoverController
的属性,其支持ivar名为\u popoverController
。您将得到OP描述的确切错误。通过查看UIToolbar.h可以看到,UIToolbar确实有自己的实例变量,名为\u delegate
。这并不是说我不相信不能碰撞,显然这是可能的。我的理解和我所学到的是,前面的下划线约定是专门为第三方开发人员引入的,这样他们就可以避免与内部IVAR发生冲突。因此,在本例中我感到惊讶……如果您查看一下UIKit类头,您会发现它们中的大多数都包含下划线前缀的ivar名称。我对该建议的理解以及我这样做的原因是,当您打算通过访问器方法访问该属性时,可以防止直接ivar访问。e、 g.name=@“Bob”
将给您一个错误,提醒/强制您使用self.name=@“Bob”当然,很多Objective-C程序员都使用直接ivar访问。当然,对于ARC来说,这没什么大不了的。无论如何,这是一个完全独立的讨论…提示:当您对UIKit类进行子类化时,请将前缀从UI更改为您自己的类使用的任何前缀。这样可以更容易地立即发现自己的类,使命名更加自然(例如,您可以使用LLToolbar而不是UIToolbarCustom),并且(最重要的是)避免使用它
@property (strong, nonatomic) id<UIToolbarCustomDelegate> delegate;