object-c(3)
来源:互联网 发布:c语言头文件作用 编辑:程序博客网 时间:2024/05/17 01:10
一些特别的概念
分类
分类(category) 又称类别, 在不修改原有的类的基础上增加新的方法. 有点像c++,继承之后可以添加自己的方法。
#import <Foundation/Foundation.h>@interface Person : NSObject{ NSString *name; int age;}
@end
如果现在要往类Person中添加一个新的方法
-(void) addCate:(NSString*) cate;
新建一个PersonCategory 类,产生.h,.m两个文件。
在PersonCategory.h文件 将PersonCategory改为Person
#import <Foundation/Foundation.h>#import "Person.h"@interface Person(cate)-(void) addCate:(NSString*) cate;@endPersonCategory.m文件
#import "PersonCategory.h"@implementation Person(cate)-(void) addCate:(NSString *)cate{ NSLog(@"dafdasfdsa=%@",cate);}@endPerson *peron=[[Person alloc] init];
[peron addCate:@"safdasfds"];当然调用addCate方法需要引入文件PersonCategory.h 文件。
协议
协议(Protocol) ,就是规定一些方法, 让其他的类遵循,遵循的方式就是在类中重写这些方法。而定义协议必须使用protocol关键字。#import <Foundation/Foundation.h>@protocol ProtocolCom<NSObject> //默认是<NSObject> 可以省略@required//用于表示协议中该方法必须在类中实现,默认[如果不加则默认为@required]-(void) eat;@optional//用于表示协议中该方法在类中可以选择实现-(void) write;@end
#import <Foundation/Foundation.h>#import "ProtocolCom.h"@protocol MyProtocol <ProtocolCom>@required-(void) setname;@optional-(void) setage;@end
在类中使用协议
#import <Foundation/Foundation.h>#import "MyProtocol.h"@interface Student : NSObject<MyProtocol>@end-------------------------------------------#import "Student.h"@implementation Student-(void) setage{ NSLog(@"Student---setage");}-(void) setname{ NSLog(@"Student----setname");}@end同时遵循多个协议
@interface className:parentName<ProtocolName1,ProtocolName2,...>
conformsToProtocol 方法用于判断某个类是否遵循某个协议,返回值为bool类型
bool flag1=[child conformsToProtocol:@protocol(NewProtocol)];
委托代理delegate
就是不想按照协议的写法来实现函数而已.
如:类A B遵循了协议 C也遵循协议 但不想在类中有实现协议中函数的代码 就可以通过委托 调用 A 或B实现的协议中的函数。
#import <Foundation/Foundation.h>#import "ProtocolName.h"@interface Student : NSObject{ id<ProtocolName> delegate;}@property (retain) id<ProtocolName> delegate;-(void) setMethod;@end---------------------------------------------#import "Student.h"@implementation Student@synthesize delegate;-(void) setMethod{ NSLog(@"Student---setMethod"); [delegate first]; [delegate second];}@end
调用:
Student *stu=[[Student alloc] init]; StudentA *stua=[[StudentA alloc] init]; StudentB *stub=[[StudentB alloc] init]; stu.delegate=stua; [stu.delegate first]; [stu setMethod]; stu.delegate=stub; [stu setMethod];
动态判断和选择器
SEL 类
SEL是选择器(selector)的一个类型。选择器就是指向方法的一个指针。
SEL对象的创建
- SEL s1 = @selector(test1); // 将test1方法包装成SEL对象
- SEL s2 = NSSelectorFromString(@"test1"); // 将一个字符串方法转换成为SEL对象
- 在内存中每个类的方法都存储在类对象中
- 每个方法都有一个与之对应的SEL类型的数据
- 根据一个SEL数据就可以找到对应的方法地址,进而调用方法
下述语句设置了一个button对象上的Action为 “@selector (start:)”,即它调用start方法:
- [button setAction:@selector(start:)];
如果你的方法上有两个参数,比如:
- -(void)setName:(NSString *)name age:(int)age;
那么,你的选择器应该这样书写:
- SEL sel = @selector(setName:age:);
如果方法不存在的话,调用该方法的应用可能会异常中止。所以,需要使用respondsToSelector 方法来判断该对象是否存在对应的方法,使用performSelector:withObject:方法来调用选择器:
- SEL sel = @selector (start:) ; // 指定action
- if ([obj respondsToSelector:sel]) { //判断该对象是否有相应的方法
- [obj performSelector:sel withObject:self]; //调用选择器方法
- }
SEL的调用方式:
- (id)performSelector:(SEL)aSelector;- (id)performSelector:(SEL)aSelector withObject:(id)object;- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;- (BOOL)respondsToSelector:(SEL)aSelector;
- @interface Person : NSObject
- - (void)test1;
- - (void)test2:(NSString *)str;
- @end
- Person *person = [[Person alloc] init];
- // 1.执行这行代码的时候会把test2包装成SEL类型的数据
- // 2.然后根据SEL数据找到对应的方法地址(比较耗性能但系统会有缓存)
- // 3.在根据方法地址调用对应的方法
- [person test1];
- // 将方法直接包装成SEL数据类型来调用 withObject:传入的参数
- [person performSelector:@selector(test1)];
- [person performSelector:@selector(test2:) withObject:@"传入参数"];
@selector
@selector 其实就是选择器,使用@selector放回SELleixing,所以SEL和@selector一般都是同时使用的。
isMemberOfClass 用于判断是否是某个类的实例
bool flag1=[stu isMemberOfClass:[Student class]];
//stu是Student类的实例,Student为Person的子类 但是stu 不能判断为Person的实例。
isKindOfClass 判断是否为某个类的实例或者某个类子类的实例
respondsToSelector 用于判断某个类型或者对象是否有能力回应(调用)指定的方法 //就是有没有这个函数
//如果info是用+声明
bool flag5=[per respondsToSelector:@selector(Info)]; //那结果就是NO bool flag6=[Person respondsToSelector:@selector(Info)]; //结果就是 yesinstancesRespondToSelector 用于判断某个对象的实例是否有能力回应(调用)指定的方法
//如果info是用+声明
bool flag7=[Person instancesRespondToSelector:@selector(eat)]; //结果为yes bool flag8=[Person instancesRespondToSelector:@selector(Info)]; //结果为No
动态调用方法
使用performSelector 方法可以动态的调用其方法,如果是实例方法则调用的需要使用对象实例,而调用静态方法这需要使用对象本身。
无参数:
[stu performSelector:@selector(eat)];[Person performSelector:@selector(Info)];
有参数:
[stu performSelector:@selector(speak:) withObject:@"ddddd"]; [stu performSelector:@selector(write:andAge:) withObject:@"fasdfadaf" withObject:@"333"];Class
先看看Class类型的代码如下:
typedef struct objc_class *Class;typedef struct objc_object { Class isa;} *id;从上面的代码可以看到Class 是结构类型,可以使用如下方式获取一个对象的Class
Class c=[Person class];
@class
由于头文件的相互包含及依赖关系,往往很小的改动就需要重新编译很多的文件。Object-C提供了一种方法可以减少由于依赖引起的重新编译:@class 来告诉编译器这是一个类,编译器只需要通过指针来引用它即可,并不需要知道关于这个类的更多信息。以此来减少编译工作。
#import <Foundation/Foundation.h>@class Person;@interface Student : NSObject{ Person *p;}@end
- object-c(3)
- object c内存管理(3)
- object-C总成3
- object-c(1)
- object-c(2)
- object-c之从"Hello World"开始(object-c)
- 第3章 Object c
- object-c 学习总结3
- Object C 入门(转)
- CHAPTER3 Practice (Object-C)
- object-c 学习(二)
- object-c 网络(中)
- object-c 网络(下)
- object-c 学习(继承)
- Object-c 基础(一)
- object-c协议(protocol)
- object-c块(block)
- Object-C:Posing(扮演)
- 如何将.sql文件导入MySQL
- android下的Juint测试
- spring事务管理
- MFC JSON解析-开源jsoncpp
- ASp.Net Websocket 服务器端实现(三)
- object-c(3)
- 部署笔记
- CEF3自研究笔记 一、使用CMake创建CEF3的vs2013的工程文件
- POJ POJ Cash Machine 多重背包
- 被点击菜单,换样式
- 使用Tomcat时8080端口无法直接映射项目的问题
- 基于Laura.Compute开发的C#科学计算器
- 机器学习之正则化(Regularization)
- ModelDriven的简单使用