3.3OC视频笔记(respondsToSelect)3.4,3.5(字符串的创建与比较方法)(详解isEqualToString)(详解isEqual)

来源:互联网 发布:华硕驱动更新软件 编辑:程序博客网 时间:2024/06/05 20:56

3.3

respondsToSelect方法:判断某一个对象中是否实现了某一个方法:例如不确定某一个类里面是否有该方法就可以用respondsToSelect方法来判断。

select代表一个方法选择器,可以表示一个方法。

aaa类的一个对象a(aaa.h文件里面定义了方法b,同时aaa.m文件里面有实现)

类本身的判断:

BOOL bool = 【a respondsToSelect:@select(b)】;这个是判断aaa类的a对象是否能实现b方法,即aaa类里面是否有b方法。返回值为布尔类型。

本类从父类继承下来的方法也算:

BOOL bool = 【a respondsToSelect:@select(isKindOfClass:)】;bool = YES;


aaa类的一个对象a(aaa.h文件里面没有定义方法b,而aaa.m文件里面有一个方法b呢?)

BOOL bool = 【a respondsToSelect:@select(b)】;      bool也为YES,所以这种情况也可以判断成功。


aaa类的一个对象a(aaa.h文件里面定义了方法b,但是aaa.m文件里面没有方法b的实现)

BOOL bool = 【a  respondsToSelect:@select(b)】;    bool = NO,所以判断失败。



3.4

OC里面的NSString对象一旦被创建就不可以被修改,如若需要一个可变的字符串对象,就需要创建NSMutableString实例。

NSString:不可变的字符串

1.创建字符串常量

NSString * str = @“xxx”;(最简单的创建方式)

str = @“yyy”;这种情况编译器是允许的,因为字符串xxx没有变化,还是存在的。

可以这样理解,str是一个指针变量,调用str是调用str指针所指向的字符串的值。这两句代码改变的不是字符串,而是改变了指向字符串的指针变量,str指向的地址不再是xxx所在的地址了,而是指向了另一个字符串yyy所在的地址,所以说NSString是不允许被修改的,允许修改的只是指向字符串的指针变量。

创建字符串

NSString * str = 【【NSString alloc】 initWithString : @"xxx"】;这种方式和方法1创建字符串是等价的。

NSString * str2 = 【【NSString alloc】initWithFormat:@“zzz,%@”,str】;这一种是字符串的拼接方法,str2的值为zzz,xxx。


2.字符串的比较(区分大小写)==和isEqualToString

NSString *str1 = @“xxx”;

NSString *str2 = @“yyy”;

str1==str2 //这个是比较两个字符串的指针变量的地址是否相同,而不是比较这两个字符串的基本值是否相同。

isEqualToString方法是判断两个字符串的内容是否相等

【str1 isEqualToString:str2】返回NO,因为内容不同。

这个isEqualToString和前面文章所说的isEqual不同点在于,前者直接判断基本类型值是否相同,后者在于判断两个代表对象的指针变量所指向的是不是同一对象。

引申问题:

第一行代码:NSString *str1 = @“zzz”;

第二行代码:NSString *str2 = @“zzz”;

编译器是怎么在内存中完成这两个变量的,str1和str2又有哪些关系。

编译器运行到第一行代码,首先编译器会在常量区里面创建一个NSString基本类型的常量zzz,(这里说一下,因为str1和str2不是类的属性,也就是说编译器会将str1和str2创建在栈里面)然后编译器会在栈里面创建局部指针变量str1,str1的值就是zzz所在常量区里面的地址,即str1指向zzz;第一行结束,编译器运行到第二行的时候,会在常量区里面先找有没有zzz这个基本类型值,如果有,便会直接使用zzz,不会去创建一个新的zzz,如果常量库里面没有zzz的话,就会创建一个新的zzz。而现在常量库里面现在 有zzz,所以不会再创建了,直接就利用现在有zzz,然后在栈里面创建一个局部的指针变量str2,让str2直接指向常量库里面的zzz,所以str2的指针和str1的指针相等,因为都是指向常量库里面的zzz。所以现在str1和str2,不管是他们两个的内容和指针都相等,而且这种情况str1==str2也是可以做到判断的,==号就是判断指针是否相同,而此时会返回YES。

在Xcode编译软件里面也可以用打断点的手段来观察str1和str2里面所存储的地址和所指向内容。

思考1,如果是下面这种情况的话呢?

NSString *str1 =  【【NSString alloc】 initWithString:@“zzz”】;

NSString *str2 =  【【NSString alloc】 initWithString:@“zzz”】;

思考2,有一种情况,在调用initWithFormat但是不出现拼接的情况呢?

NSString *str1 = 【【NSString alloc】 initWithFormat:@“zzz”】;

NSString *str2 = 【【NSString alloc】 initWithFormat:@“zzz”】;

按理来说上面这两种情况出现的话,会在堆中创建str1和str2这两个对象,而涉及到堆的时候自然就与前面没有提到堆,光在栈和常量库里面创建对象的情况就不一样了(下回有涉及到堆的情况),但是OC做出了优化,像上面这两种情况调用initWithString和调用initWithFormat(调用但不进行拼接)是不需要在堆中创建对象的,所以上面的两个小思考和前面NSString *str1 = @“zzz”;NSString *str2 = @“zzz”;的例子是一样的。

思考3,如果是调用initWithFormat同时进行拼接呢?

NSString *str1 =  【【NSString alloc】 initWithFormat:@“zzz%@”,@“aaa”】;

NSString *str2 =  【【NSString alloc】 initWithFormat:@“zzz%@”,@“aaa”】;

像这种情况,编译器就会用到了堆,首先会在堆里面创建str1和str2对象,注意在堆里面就是两个对象而不是指针变量了,然后堆里的两个对象会指向常量库里面的zzzaaa基本类型常量,无可厚非,常量当然还是一个,所以两个对象的内容还是相同的。然后在栈里面还是会有str1和str2的两个局部指针变量,但是此时这两个指针变量指向的就是堆中的str1和str2的两个对象了,都说了是两个对象,所以栈里面的str1和str2指针变量当然就不同了,所以两个对象的指针是不同的,用==判断的话,返回的就是NO了。

思考3:调用isEqual判断会返回YES or NO?

如果是光创建字符串对象,而不进行拼接的话:

我试了一下,isEqual返回的是YES。

但是要进行拼接呢?

我试了一下,isEqual返回的是YES。

为什么呢?明明如果是两个字符串并接的话,他们两个的指针是不相等的,只有属性(基本类型值是相等的啊)。

下面来详细讲解一下OC里面的isEqual:

首先贴歌苹果官方重写isEqual 的demo

  1. - (BOOL)isEqual:(id)other {  
  2.  if (other == self)   
  3.  return YES;  
  4.  if (!other || ![other isKindOfClass:[self class]])  
  5.  return NO;  
  6.  return [self isEqualToWidget:other];  
  7. }  
  8.  
  9. - (BOOL)isEqualToWidget:(MyWidget *)aWidget {  
  10.  if (self == aWidget)  
  11.  return YES;  
  12.  if (![(id)[self name] isEqual:[aWidget name]])  
  13.  return NO;  
  14.  if (![[self data] isEqualToData:[aWidget data]])  
  15.  return NO;  
  16.  return YES;  
  17. }
简单说一下:

首先都会判断 指针是否相等 ,相等直接返回YES,

不相等再判断是否是同类对象或非空,空或非同类对象直接返回NO,

而后依次判断对象对应的属性是否相等,若均相等,返回YES

所以,对于思考3,两个都是YES就清晰了。


3.字符串比较(不区分大小写)caseInsensitiveCompare

调用caseInsensitiveCompare这个方法,该方法的返回值是一个枚举,需要创建一个枚举对象进行接收。例

NSString * str1 = @“kunsidiele”;

NSString* str2 = @“KUNsiDIEle”;

NSComparisonResult result = 【str1 caseInsensitiveCompare:str2】;

if(result == @“NSOrderedSame”){

        NSLog(@“两个困死爹了在不区分大小写的情况一样”);

}


4.比较字符串大小(当然区分大小写,比较的是ASCII码)(数值也可以比较)compare

NSString *str1 = @“a”;

NSString *str2 = @“b”;

NSComparisonResult result = 【str1 compare:str2】;

if(result == NSOrderedAscending){

NSLog(@“str1<str2”);

}

if(result == NSOrderedame){

NSLog(@“str1 = str2”);

}

if(result = NSOrderedDescending){

NSLog(@“str1>str2”);

}

看代码应该秒懂。





。。。。。。over


0 0
原创粉丝点击