Ios ivar问题

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

我正在对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
但是,在这个场景中,它给了我一个错误:

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委托;
@结束
注:

  • 类前缀已删除

  • 代理声明已被删除(我使用的是ios代理教程代码,但代码示例使用的是旧的xcode版本,其中需要声明)

  • 合成被移除了,我也不知道我们不再需要合成我们的属性了

  • PS:显然代码不起作用,因为ivar问题。我要改变它的名字,所以我不需要合成它,也不知道用什么名字

    这是怎么回事?UIToolbar类中是否有名为_delegate的私有实例变量

    是的,这正是问题所在。您需要为实例变量提供不同的名称<代码>\u委托人将起作用,或者您可以在名称前面加上3个字母的前缀(参见最后一段)

    请注意,您已将ivar声明为
    委托
    ,然后在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”@property (strong, nonatomic) id<UIToolbarCustomDelegate> delegate;