注册 登录
筛选: 全部
主题 : 类别不是应该只能添加方法吗?类别现在能直接添加属性了?
级别: 新手上路
UID: 170378
精华: 0
发帖: 21
可可豆: 51 CB
威望: 51 点
在线时间: 30(时)
注册时间: 2012-10-09
最后登录: 2016-01-26
0 楼:  发表于: 2013-01-18 14:59    发自: Web Page

类别不是应该只能添加方法吗?类别现在能直接添加属性了?   

  • 技术问题发到问答


有一个标签控制器TabBarController,控制器类XFirstViewController作为其中的一个标签,
新建一个视图控制器类XFirstViewController:UIViewController
在XFirstViewController.m文件中,在init方法中设置视图的标签项标题跟图片,

        self.title = @"Quotes";
        self.tabBarItem.image = [UIImage imageNamed:@"Quotes"];
关于self.tabBarItem这个属性,查看此属性定义的地方,会跳转到UITabBarController.h文件的如下定义:

@interface UIViewController (UITabBarControllerItem)
@property(nonatomic,retain) UITabBarItem *tabBarItem
@property(nonatomic,readonly,retain) UITabBarController *tabBarController; 
@end
分析这段代码:这是UIViewController类的一个类别(UITabBarControllerItem),类别中新添加了2个属性tabBarItem与tabBarController。
也就是说UIViewController类新加了2个属性。
问题1,类别不是应该只能添加方法吗?类别现在能直接添加属性了?


就算类别能扩展属性了,接着上面说self.tabBarItem这个属性,self代表的是XFirstViewController类,此类是UIViewController的子类,UIViewController类自己就有一个属性
    UITabBarItem     *_tabBarItem;
问题2:既然UIViewController类自身有了一个UITabBarItem *_tabBarItem的属性,为什么还要用类别扩展出一个@property(nonatomic,retain) UITabBarItem *tabBarItem属性?self.tabBarItem与self._tabBarItem有什么关联和区别?


同样的情况发生在UINavigationController类身上,在UINavigationController.h文件中

@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,retain) UINavigationItem *navigationItem; 
@property(nonatomic) BOOL hidesBottomBarWhenPushed; 
@property(nonatomic,readonly,retain) UINavigationController *navigationController; 
@end
同样UINavigationController也是UIViewController的子类,UIViewController本身也拥有一个属性:

    UINavigationItem *_navigationItem;


同问,既然UINavigationItem类自身有了一个UINavigationItem的属性,为什么还要用类别扩展出一个
UINavigationItem *navigationItem属性?self.navigationItem与self._navigationItem有什么联系?



请大家能指导一下,谢谢。



级别: 版主

状态: 连续签到 - [1天]
UID: 85617
精华: 1
发帖: 4122
可可豆: 32422 CB
威望: 35741 点
在线时间: 1260(时)
注册时间: 2011-08-06
最后登录: 2018-04-10
1 楼:  发表于: 2013-01-18 15:20    发自: Web Page
问题1: 这样确实是添加了property,但是只能在原类中使用,也就是是说你在@implement UIViewController (UITabBarControllerItem) 里是无法使用的,只能在@implement UIViewController里用,那么不就等于没有添加么。所以才说category是不能添加property的。
问题2:你还不明白property和local variable的区别。还有,点号其实是方法,也就是getter/setter,所以应该不存在self._navigationItem这种东西
TerryLin
2011年冬季斯坦福大学公开课:iOS应用开发教程
http://www.cocoachina.com/bbs/read.php?tid=88801
级别: 新手上路
UID: 170378
精华: 0
发帖: 21
可可豆: 51 CB
威望: 51 点
在线时间: 30(时)
注册时间: 2012-10-09
最后登录: 2016-01-26
2 楼:  发表于: 2013-01-18 17:32    发自: Web Page
回 1楼(linlinyao1) 的帖子
多谢版主指导,
对于问题1:添加的属性虽然在@implement UIViewController (UITabBarControllerItem) 类别类里无法使用。但是在外面的类,比如XFirstViewController类中,可以使用self.tabBarItem来访问新加的属性。这样不是给UIViewController类增加了属性吗?

对于问题2:self._navigationItem这个确实用错了,直接使用_navigationItem就好。
我理解的属性与成员变量的关系:
1,属性就是与属性相对应的成员变量的值。在使用属性的时候,其实本质也是对成员变量的值进行操作。虽然不能说等同,但是基本是差不多的。
2,有些成员变量会声明为属性,有些成员变量没有声明为属性。
例如:UIViewController类定义中有这些成员变量:

    @package
    UIView           *_view;
    UITabBarItem     *_tabBarItem;
    UINavigationItem *_navigationItem;
    NSArray          *_toolbarItems;
    NSString         *_title;
    ... }
其中_view与_title被声明为了属性:
@property(nonatomic,retain) UIView *view;
@property(nonatomic,copy) NSString *title;
请问下版主,为什么_tabBarItem, _navigationItem这2个成员变量为什么没有申明为属性?
如果把他们申明为属性,那不就可以不用用类别来扩展@property(nonatomic,retain) UITabBarItem *tabBarItem; 属性了。
而且基本没有看到使用过_tabBarItem, _navigationItem这2个成员变量。基本都是使用的类别扩展出来的属性。

级别: 版主

状态: 连续签到 - [1天]
UID: 85617
精华: 1
发帖: 4122
可可豆: 32422 CB
威望: 35741 点
在线时间: 1260(时)
注册时间: 2011-08-06
最后登录: 2018-04-10
3 楼:  发表于: 2013-01-19 01:05    发自: Web Page
回 2楼(itianyi) 的帖子
1,确实是这样的,不过要注意到,这样做的话,你就不能去实现该category的implement,否则会报错。

2,默认情况下,操作属性和操作成员变量是一样的,只是在非arc下还会帮你写好了release。不过如果你重载了setter和getter情况就变了,有时候一些操作比如在设置属性之后要更新界面,就要在setter里写。
根据苹果文档http://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/Category.html, _tabBarItem, _navigationItem这2个成员变量为什么没有申明为属性的原因是为了把类写得更分散更解耦。
TerryLin
2011年冬季斯坦福大学公开课:iOS应用开发教程
http://www.cocoachina.com/bbs/read.php?tid=88801
级别: 骑士
UID: 128606
精华: 0
发帖: 324
可可豆: 1476 CB
威望: 1476 点
在线时间: 567(时)
注册时间: 2012-03-08
最后登录: 2018-07-09
4 楼:  发表于: 2013-01-19 11:08    发自: Web Page
好像不是不能在类别里添加属性,而是不能在类别里添加成员变量。
属性并不一定会有对应的成员变量吧
级别: 新手上路
UID: 170378
精华: 0
发帖: 21
可可豆: 51 CB
威望: 51 点
在线时间: 30(时)
注册时间: 2012-10-09
最后登录: 2016-01-26
5 楼:  发表于: 2013-01-20 10:42    发自: Web Page
回 4楼(neestream) 的帖子
属性肯定会有对应的成员变量,如果你自己不写,系统会默认给你生成一个以下划线开头的成员变量
级别: 新手上路
UID: 170378
精华: 0
发帖: 21
可可豆: 51 CB
威望: 51 点
在线时间: 30(时)
注册时间: 2012-10-09
最后登录: 2016-01-26
6 楼:  发表于: 2013-01-20 10:43    发自: Web Page
回 3楼(linlinyao1) 的帖子
多谢版主大人的解惑,万分感谢
级别: 骑士
UID: 128606
精华: 0
发帖: 324
可可豆: 1476 CB
威望: 1476 点
在线时间: 567(时)
注册时间: 2012-03-08
最后登录: 2018-07-09
7 楼:  发表于: 2013-01-21 08:57    发自: Web Page
回 5楼(itianyi) 的帖子
那你自己试试给NSString建个类别,然后添加个属性试试,如果你啥代码都不写,编译器会警告你,而不会自动生成  _开头的成员变量。

属性其实是get和set方法,如果你只写get和set方法,而不写成员变量,也可以当做属性访问。

比如我不用@property声明,但是声明和实现方法  setAge   age

那么我的类也拥有age属性

所以,类别里添加属性是可以的,但是不能添加成员变量
级别: 精灵王

UID: 68508
精华: 0
发帖: 893
可可豆: 3670 CB
威望: 3665 点
在线时间: 681(时)
注册时间: 2011-05-07
最后登录: 2017-08-04
8 楼:  发表于: 2013-01-22 10:00    发自: Web Page
回 7楼(neestream) 的帖子
楼上分析到位,赞一个
不过“那你自己试试给NSString建个类别,然后添加个属性试试,如果你啥代码都不写,编译器会警告你,而不会自动生成  _开头的成员变量。”
这句倒也不是绝对的,xcode 4.5上试试呢,定义了@property,根本不用你写@synthesize,照样work
级别: 新手上路
UID: 167652
精华: 0
发帖: 29
可可豆: 29 CB
威望: 29 点
在线时间: 84(时)
注册时间: 2012-09-20
最后登录: 2016-01-08
9 楼:  发表于: 2013-01-22 21:32    发自: Web Page
其他的我不清楚,但匿名类别里面是可以添加成员变量的,我在项目开发过程使用过的,没有问题。
至于,匿名类别里面添加私有属性与私有方法就更没有问题,苹果官方文档为证:
还有自iOS6开始,属性可以省略@synthesize编译指令的,编译器会自动为对应属性添加“_属性名”
的成员变量。但是如果你想改变这种默认行为,也可显式地调用@synthesize指令为属性指定成员
变量名。
图片:屏幕快照 2013-01-22 下午9.27.20.png

本站内容均为本站转发,已尽可能注明出处。因未能核实来源或转发内容图片有权利瑕疵的,请及时联系本站,本站会第一时间进行修改或删除。 QQ : 3442093904

描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部