ObjC的基本特征

1. ObjC一般要点

  1. OC中所有对象类型的变量都必须加上”*”,在ObjC中对象其实就是一个指针.
  2. ObjC中使用[ ]来进行方法调用,本质其实就是发送消息.
  3. ObjC中方法分为静态方法和动态方法,动态方法就是对象方法,静态方法就是类方法.
  4. 公共成员(public)的调用可以使用”->”操作符.
  5. 成员变量和属性: 通常一个成员的访问不会直接通过成员变量 而是通过属性暴露给外界.ObjC中实现属性就是通过set和get方法来实现.
成员属性的声明方式:
  1. 如果只声明一个属性”a” : 编译器会使用”_a”作为属性的成员变量 (如果没有定义成员变量_a则会自动生成一个私有的成员变量_a; 如果已经定义了成员变量_a则使用定义的;注意:如果此时定义的成员变量是a,则此时依旧会自动生成一个成员变量_a,它跟自定义成员变量a没有任何关系);
  2. 如果声明一个属性”a”,且使用@synthesize a进行实现,但是实现过程中没有指定使用的成员变量 : 此时编译器会使用”a”作为属性的成员变量 (如果定义了成员变量a,则使用这个自定义的;如果没有定义则会自动生成一个私有的成员变量a; 如果定义了的是 _a,没有任何关系)
  3. 如果声明了一个熟悉a,使用@synthesize a = _a 实现; 这个过程已经指定了使用的成员变量, 此时会使用指定的成员变量作为属性变量.

通常在实际开发过程中我们要么 直接在@property中声明不使用@synthesize (1);要么 使用过程中指定具体的成员变量(3).

声明属性还可以使用@dynamic关键字,相对于@synthesize表示告诉编译器不自动生成setter和getter方法.避免编译期间的警告;
然后根据需要自己实现存取方法或是 在运行时动态绑定(主要用于在CoreData的实现NSManagedObject子类时使用,由Core Data框架在程序运行时的动态生成子类属性)

自定义构造方法.init
-(instance)initWithName:(NSString*) name age:(int)age {
    if(self = [super init]) {
        self.name = name;
        self.age = age; 
    }
    return self ;
}
description方法

在C#中每个类都有一个ToString()方法,JAVA中叫toString(), 都是用于打印一个对象的信息;在ObjC中这个方法叫做description.默认输出类名和地址. 重写此方法用于调试;(注意:不能在此方法中打印输出self,死循环)

-(NSString *)description{
    return [NSString stringWithFormat:@"{name:%@,age:%i}",self.name,self.age];
}

OC中的多继承

多继承是从多个直接基类派生 类的能力,可以更加直接为应用程序建模;

而ObjC不支持多继承,这是由于消息机制中 名字查找发生运行时而非编译时,很难解决多个基类可能导致的二义性问题;

不过我们可以使用间接实现多继承的目的: 三种方法: 代理,类别和消息转发.

1. 代理和协议

委托是ObjC中最常见的一种回调机制,可以实现多继承效果.

2.类别

用分类直接添加方法,并利用运行时添加实例变量.

3. 消息转发:

当向someObject发送消息,但runtime system在当前类和父类中都找不到对应方法的实现时,runtime system并不会立即报错崩溃,而是依次执行以下步骤:
这里写图片描述

  1. 动态方法解析: 向当前类发送resolveInstanceMethod:信号, 检查是否动态向该类添加了方法.(@dynamic);
  2. 快速消息转发: 检测该类是否实现了forwardingTargetForSelector:方法 ,如果实现就调用; 若该方法返回值对象非nil或非self, 则向该返回对象 重新发送消息.
    • 标准消息转发: runtime发送methodSignatureForSelector:消息获取Selector对应的方法签名. 返回值非空则通过forwardInvocation:转发消息,返回值为空就会向当前对象发送doesNotRecognizeSelector:消息崩溃退出;

利用上述的过程的2,3两步可以完成消息转发的两种方式;

3.1 快速消息转发

实现很简单,只需重写- (instances)forwardingTargetForSelector:(SEL)aSelector,就可以让A类调用B类的方法,从而实现多继承的目的:

//例. Teacher类实现 将消息转发给Doctor,
-(instances)forwardingTargetForSelector:(SEL)aSelector {
    Doctor *doctor = [[Doctor alloc] init];
    if([doctor respondsToSelector:aSelector]) {
        return doctor;
    }
    return nil;
}

虽然消息可以动态转发传递,但是编译器的静态检查不通过,需要给Teacher声明要调用的方法,但是Teacher没有实现,如何声明,两种方式解决:

  1. 声明方法-类别: 给Teacher添加分类,在其中声明operator方法.
  2. 导入头文件, 进行类型强转: 包含Doctor头文件,告诉编译器区Doctor中找operator方法的声明,并在调用时强转类型:Teacher *teacher = [[Teacher alloc]init];
    ; [(Doctor *)teacher operate];
3.2 标准消息转发

标准消息转发重写 methodSignatureForSelector: 和 forwardInvocation:两个方法即可。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector   
{   
    NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];   
    if (signature==nil) {   
        signature = [someObj methodSignatureForSelector:aSelector];   
    }   
    NSUInteger argCount = [signature numberOfArguments];   
    for (NSInteger i=0 ; i
    }   

    return signature;   
}   

- (void)forwardInvocation:(NSInvocation *)anInvocation   
{   
    SEL seletor = [anInvocation selector];   
    if ([someObj respondsToSelector:seletor]) {   
        [anInvocation invokeWithTarget:someObj];   
    }   

}   

两种消息转发方式比较: 快速消息转发: 简单快速,但是仅能转发给一个对象. 标准消息转发:复杂,转发可控,可以实现多对象转发.


多态

  • 多态: 不同对象以自己的方式响应相同的消息.
  • 目的: 简化编程接口,容许在类与类之间重用一些习惯性的命名,而不用为每一个新加的函数想一个新名字.
  • 原理:每个类都属于该类的名字空间,类定义中的名字和类定义外的名字不冲突. 动态绑定.

多态的具体实现:
在ObjC中是通过一个叫做selector的选取器实现的,在Object-C中selector有两个意思:

  1. 当给对象的源码消息时,用来指方法的名字;
  2. 在源码编译后代替方法名的唯一标识;

选取器特点:所有同名的方法拥有同样的选取器. 所有选取器都不同;

  1. SEL和@selector:选择器类型是SEL. @selector指示符用来引用选择器, 返回类型是SEL.
    • 例: SEL response;
      response = @selector(load:)
    • 通过字符串来得到选取器:responseSEL = NSSelectorFromString(@"loadDataForTableView:");
    • 通过方向转换,得到方法名: NSString *methodName = NSStringFromSelector(responseSEL);
  2. 方法和选取器: 选取器确定的是方法名,不是方法的实现, 设施多态和动态绑定的基础.它使得向不同对象发送相同的消息成为现实.
  3. 方法返回值和参数类型: 消息机制是通过选取器找到方法的返回值类型和参数类型. 因此: 动态绑定需要同名方法的实现 拥有相同返回值类型和相同的参数类型;否则,运行时可能出现找不到对应方法的错误.(有一个例外,虽然同名类方法和实例方法拥有相同的选取器,但是它们可以有不同的参数类型和返回值类型。)

Foundation框架概念:

  • 框架是由许多类.方法.函数.文档按照一定的逻辑组织起来的集合,以便使研发程序
    变得更容易,在OS X下得Mac操作系统中大约有8个框架,其中为所有程序开发奠定基础的框架 称为Foundation框架.

  • Foundation框架允许使用一些基本对象,如数字和字符串,以及一些对象集合,如数组,字典和集合.其他功能包括处理日期和时间,内存管理,处理文件系统,几何数据等.


1.1NSString的基本使用
  1. 创建方式:
    1) NSString *str=@”abc”//常量字符串
    2)格式化创建–存放在堆区–对象字符串
    快速创建格式:NSString *str=[NSString stringWithFormat:@”abc:%@”,@”ddd”]/
  2. 字符串文件读写:

写入文件:
-(BOOL)writeToFile: path atomically: YES encoding:NSUTF8String error :(NSError类型的二级指针) ;

NSError *err;
NSString str=@"北京";
//写入文件
[str writeTOFile:@"/../../1.txt" atomically:YES encoding:NSUTF8String error :err];
//判断是否写入错误
if(err!=nil){
    NSLog(@"写入失败");
    NSLog(@"%@"[err localizedDescription]);    //打印错误信息
}else{
    NSLog(@"写入成功");
}

读:+(Instancetype)stringWithContentsOfFile:路径encoding:NSUTF8StringEncoding error:&err

类似的NSURL读写字符串
URL全称Uniform Resource Locator (统一资源定位符)
URL是互联网上标准资源的地址,每个资源都有唯一的URL;
基本URL==协议头://服务器域名(IP)/路径
常见的URL协议头:http\https:超文本传输协议资源,网络资源.

https表明用SSL加密的,与服务器信息传输更安全.
web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定.http与s使用的是完全不同连接方式,端口也不同,前者是80,后者443.http链接很简单,无状态的 .https协议有SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议.更安全

传入完整的字符串创建:
+(instancetype) URLWithString:(nonnull NSString )//即路径,no null表示不能为空. * 通过这种方式创建NSURL对象, 需要指定协议类型, 比如”http://” 、 “ftp://” 、 “file://” 、”https://”等协议。
通过这种方式创建的NSURL, 如果路径中有中文, 则无法正常使用, 需要使用下面的方 式来创建。**

(通过文件路径创建): +(instancetype) fileURLWithPath:路径
默认就是读取本地文件的NSURL对象, 路径以”file://” 开头

读取:+(instancetype)stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:
&err];


String.Array.Dictionary.等集合类.
读写文件都是用以上两种方式(本地文件和服务器):
写入(创建文件):-(bool)writeToFile/writeToUrl
读取: +(id)类型WithContentOfile/OfUrl


2.NSString常见方法:
  1. -(NSString *)uppercaseString;转换大写
  2. -(NSString*)lowercaseString;变小写
  3. -(NSString*)capitallizedString 首字变母大写,其他小写
    ……..具体查看foundation框架目录.

截取

 //        1,从字符串的开始位置,截取到指定的位置(不包含指定的位置)//从0开始
NSString *subStr = [str substringToIndex:3];
//
//        2,从指定的位置,截取到字符串的末尾(包含指定的位置)
subStr = [str substringFromIndex:3];

//        3,指定一个范围,截取这个范围内的字符串
NSRange r1 = {11,7};
subStr = [str substringWithRange:r1];
4.NSArray

只能存放任意OC对象, 并且是有顺序的;
可用%@直接打印数组结果
1 .创建方法(类):

  • (instancetype)array;//空字符串,且不可变
  • (instancetype)arrayWithObject:(id)anObject;
  • (instancetype)arrayWithObjects:(id)firstObj, …;
  • (instancetype)arrayWithArray:(NSArray *)array;
  • (id)arrayWithContentsOfFile:(NSString *)path; // 读取一个xml文件.

    • (id)arrayWithContentsOfURL:(NSURL *)url; // 读取一个xml文件.

2.对象方法创建,

-(instancetype)initWithObjects:@”one”,@”two”,nil

3用已经存在的数组

initWithArray:arr

NSArray直接使用NSLog()作为字符串输出时是小括号括起来的形式。 NSArray中不能存储nil,因为NSArray认为nil是数组的结束(nil是数组元素结束的标记)。nil 代表0。而0是基本数据类型,不能存放到NSArray中。

简写:创建NSString arr= @[@"one",@"two"]

获取元素简写:arr[1];

三种遍历方式:

  1. 普通for循环 for {NSLog( arr[i])}

  2. 快速遍历:for(NSString *str in arr) {NSLog (str)}

  3. block遍历: arr enumerateObjectsUsingBlock:^(id obj,NSUInteger idx,BOOl *stop){ NSLog 下标:idx 值:obj}
    *stop用来控制输出,例:if(idx==1){ *stop=YES;}表示输出到下标为1时结束.

5.NSDictionary字典

作用:通过一个key(键), 就能找到对应的value(值)

简写:@{@"zs" : @"zhangsan", @"ls" : @"lisi", @"ww" : @"Wangwu"};
特点:

  1. 字典存储的时候,必须是”键值对”的方式来存储(同时键不要重复)
  2. 键值对中存储的数据是”无序的”.
  3. 键值对集合可以根据键, 快速获取数据.

遍历: for(NSString *keyStr in dict){
NSLog(@”%@=%@”,keyStr,[dict objectForKey:keyStrl])
//获得对应key的值.可简写 dict[@"name”];

block遍历法
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
}];

  • NSArray和NSDictionary的区别
    1> NSArray是有序的,NSDictionary是无序的
    2> NSArray是通过下标访问元素,NSDictionary是通过key访问元素

  • NSArray的用法
    1> 创建
    @[@”Jack”, @”Rose”] (返回是不可变数组)
    2> 访问
    id d = array[1];
    3> 赋值
    array[1] = @”jack”;

  • NSDictionary的用法
    1> 创建
  • @{ @”name” : @”Jack”, @”phone” : @”10086” } (返回是不可变字典)
    +2> 访问
    id d = dict[@”name”];
    3> 赋值
    dict[@”name”] = @”jack”;
3.可变Mutable系列.

NSMutableString.NSMutableArray等.


    • 可变都是不可变的子类.
  • 可变表示:内存地址固定,内存空间和内容可以改变;
    不可变:皆不可变.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值