学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

Protocol in ObjC

如何处理带有property的Protol

1
2
3
4
5
6
7
8
9
10
11
@protocol MyProtocol <NSObject>

@required

@property (readonly) NSString *title;

@optional

- (void) someMethod;

@end

我见过使用这种格式,而不是编写子类继承的具体超类。问题是,如果你遵循这个协议,你需要自己合成属性(synthesize the properties)吗?如果要继承超类,答案显然是否定的,您不需要这样做。但是如何处理协议需要遵守的属性呢?

根据我的理解,您仍然需要在遵循需要这些属性的协议(conforms to a protocol)的对象的头文件中声明实例变量。在这种情况下,我们可以假设它们只是一个指导原则吗?显然,对于必需的方法,情况并非如此。如果你排除了协议中列出的一个必需的方法,编译器会给你一记耳光。属性背后的故事是什么呢?

下面是一个生成编译错误的示例(注意:我已经修剪了不反映手头问题的代码):

1
2
3
4
5
6
@protocol MyProtocol <NSObject>

@required
@property (nonatomic, retain) id anObject;

@optional
1
2
3
4
5
6
7
8
9
10
11
- (void)iDoCoolStuff;

@end

#import <MyProtocol.h>

@interface TestProtocolsViewController : UIViewController <MyProtocol> {

}

@end
1
2
3
4
5
6
7
8
9
10
11
12
#import "TestProtocolsViewController.h"

@implementation TestProtocolsViewController
@synthesize anObject; // anObject doesn't exist, even though we conform to MyProtocol.

- (void)dealloc {
[anObject release]; //anObject doesn't exist, even though we conform to MyProtocol.
[super dealloc];
}

@end

Answer

协议只是通过协议告诉所有知道你的类的人,属性anObject会在那里。协议不是真实存在的,它们本身没有变量或方法——它们只是描述了一组特定的属性,这些属性是关于你的类的,因此持有它们引用的对象可以以特定的方式使用它们。

这意味着在符合协议的类中,你必须做所有的事情来确保anObject工作。

@property@synthesize是为您生成代码的两种核心机制。@property只是说会有getter(或setter)方法用于那个属性名。现在,仅@property就足以拥有系统为您创建的方法和存储变量(过去必须添加@sythesize)。但是你必须有东西来访问和存储变量。

对于协议中定义的属性,即使在现代运行时中,您仍然需要“@synthesize”,或者您需要在接口定义中复制“@property”以获得自动合成。

Objective-C中的@property和@synthesize用法

@property与@synthesize配对使用。
功能:让编译器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。

property属性
作用:提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境。
使用范围:property不但可以在interface,在协议protocol和类别category中也可以使用。

synthesize 合成访问器方法
作用:实现property所声明的方法的定义。其实说直白就像是:property声明了一些成员变量的访问方法,synthesize则定义了由property声明的方法。

他们之前的对应关系是:property 声明方法 ->头文件中申明getter和setter方法 synthesize定义方法 -> m文件中实现getter和setter方法。
如:

在头文件中:@property int count; 等效于在头文件中声明2个方法:

1
2
- (int)count;  
-(void)setCount:(int)newCount;

实现文件(.m)中`@synthesize count; 等效于在实现文件(.m)中实现2个方法。

1
2
3
4
5
6
7
8
 - (int)count
{
return count;
}
-(void)setCount:(int)newCount
{
count = newCount;
}
  • 在Xcode4.5及以后的版本中,可以省略@synthesize,编译器会自动帮你加上getset 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量。
  • 注意:iOSsettergetter方法不可以同时写,在.m文件中同时实现gettersetter时候需要@synthesize age = _age.表示要手动生成settergetter方法,同时用age的地方可以用_age_age是写在花括号里的字段,而age@property里声明的属性,字段是私有的,而属性可以供外界访问,私有字段在校验数据合法性等情况(尤其是在安全方面)有着积极作用。

Protocol VS Base Class

参考

How to handle Objective-C protocols that contain properties