【iOS】——==与isEqual方法

在OC中,有两种可以判断两个变量是否相等,一种是利用 == 运算符,另一种是利用isEqual方法。

1.当使用 == 来判断两个变量是否相等时,如果两个变量是基本类型的变量,且都是数值型(不一定要求数据严格一致),则只要两个值相等,使用 == 判断就返回真。
2.对于两个指针类型的变量,它们必须指向同一个对象(也就是两个指针变量保存的内存地址相同),== 判断才会为真。当使用 == 比较类型上没有继承关系的两个指针变量时,编译器会提示警告。

“==”方法

基本类型的数据使用“==”判断:

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        int it = 65;
        float fl = 65.0f;
        //验证两个变量是基本类型的变量,且都是数值型(不一定要求数据严格一致),只要数值相同就为真
        //输出1
        NSLog(@"%d", (it == fl));
        char ch = 'A';
        //输出1
        NSLog(@"%d", (it == ch));
    }
    return 0;
}

字符串使用“==”判断:

引例:

示例1:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = @"555";
        NSString* str2 = @"555";
        NSLog(@"%d", (str2 == str1));
     }
    return 0;
}

在这里插入图片描述

示例2:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = [NSString stringWithFormat:@"hello"];
        NSString* str2 = [NSString stringWithFormat:@"hello"];
        //使用“==”判断字符串,输出0
        NSLog(@"%d", (str1 == str2));
     }
    return 0;
}

在这里插入图片描述

以上两个代码说明字符串的创建方式会影响判断是否相等。想要弄清楚原因先要搞清楚它们是怎么创建及存放的。

字符串的两种创建方式:

  1. NSString *string1 = @“iPhone”;
  2. NSString *string6 = [NSString stringWithFormat:@"%@ %@",string1,string2];

两种创建的区别:

1.第一种创建好字符串放入常量池中,常量池会保证相同的字符串直接量只有一个,不会产生多个的副本,示例1中的s1、s2都指向常量池中的同一个字符串对象,所以示例1的结果是1。
2.使用第二种类方法创建的字符串对象是运行时创建出来的,它==被保存在运行时内存区(即堆内存),不会放入常量池;因此,示例2中的两个指针变量不相同。

isEqual方法

在很多时候,程序判断两个指针变量是否相等,也希望能有一种类似于“值相等”的类来判断规则,并不严格要求指向同一个对象。这时候就可以用isEqual方法。

isEqual:方法是NSObject类提供的一个实例方法,因此,所有的指针变量都可以调用该方法来判断是否与其他指针变量相等。 NSObject默认提供的isEqual:只是比较对象的地址,即NSObject类的isEqual:方法比较的结果与“ == ”运算符比较的结果完全相同。因此这个NSObject类提供的isEqual没有太大的实际意义。
示例1:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSObject* str1 = [[NSObject alloc]init];
        NSObject* str2 = [[NSObject alloc]init];
        NSLog(@"%d", [str1 isEqual:str2]);
     }
    return 0;
}

效果:
在这里插入图片描述

如果希望可以采用自定义的相等标准,则可采用重写isEqual方法来实现,NSString已经重写了isEqual:方法判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过isEqual:比较返回真,否则返回假。

示例1:NSString的isEqual重写

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = [NSString stringWithFormat:@"hello"];
        NSString* str2 = [NSString stringWithFormat:@"hello"];
        NSLog(@"%d", [str1 isEqual:str2]);
     }
    return 0;
}

在这里插入图片描述

示例2:用户自定义重写

//FKapple.h
#import <Foundation/Foundation.h>

@interface FKapple : NSObject
@property (nonatomic, assign) int height;
@end
//FKapple.m
#import "FKapple.h"

@implementation FKapple
- (BOOL) isEqual:(id)object
{
    
    
    //不进行判断,总是返回YES,即FKApple对象与任何对象都相等
    return YES;
}
@end
#import <Foundation/Foundation.h>
#import "FKapple.h"

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        FKapple* a1 = [[FKapple alloc]init];
        NSObject* a2 = [[NSObject alloc]init];
        NSLog(@"%d", [a1 isEqual:a2]);
     }
    return 0;
}

效果:
在这里插入图片描述

上面的代码重写了NSObject类的isEqual:方法,重写该方法时并未加判断,直接返回了YES,这将导致FKapple对象与任何对象比较都返回YES。

isEqual的重写需满足以下的条件:

  1. 自反性:对任意x,[x isEqual : x]一定返回真
  2. 对称性:对任意x和y,如果[y isEqual: x]返回真,则[x isEqual: y]也返回真。
  3. 传递性:对任意x、y、z,如果有[x isEqual: y]返回真,[y isEqual: z]返回真,则[x isEqual: z]一定返回真。
  4. 一致性:对任意x和y,如果对象中用于等价比较的关键信息没有改变,那么无论调用[x isEqual: y]多少次,返回的结果都应该保持一致,要么一直为真,要么一直为假。
  5. 对任何不是nil的x,[x isEqual: nil]一定要返回假。

关于字符串的类型管理与“==”、isEqual方法

示例1:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = [NSString stringWithFormat:@"hellowwwwwww"];
        NSString* str2 = [NSString stringWithFormat:@"hellowwwwwww"];
        //使用“==”判断字符串,输出0
        NSLog(@"%d", (str1 == str2));
        //使用isEqua判断字符串,输出1
        NSLog(@"%d",[str1 isEqual:str2]);
    }
    return 0;
}

这种情况下,字符串类型为_NSCFString,这种状态下即使是相同的内容也会存放在不同的地址里,所以"=="输出为0,isEqual输出为1。

示例2:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = [NSString stringWithFormat:@"hello"];
        NSString* str2 = [NSString stringWithFormat:@"hello"];
        //使用“==”判断字符串,输出为1
        NSLog(@"%d", (str1 == str2));
        //使用isEqua判断字符串,输出1
        NSLog(@"%d",[str1 isEqual:str2]);
    }
    return 0;
}

这种情况下,字符串类型为NSTaggedPointerString类型,这种状态下当字符串的内容相同时,地址也会相同,所以两种判断下输出都为1。

示例3:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSString* str1 = @"wwwwwwwww";
        NSString* str2 = @"wwwwwwwww";
        //使用“==”判断字符串,输出1
        NSLog(@"%d", (str1 == str2));
        //使用isEqua判断字符串,输出1
        NSLog(@"%d",[str1 isEqual:str2]);
    }
    return 0;
}

这种情况下,字符串类型为__NSCFConstantString类型,这种状态下字符串储存在常量区,所以两个字符串都指向同一个地址,所以输出都为1。

总结:“==”是运算符,isEqual是方法;“ ==”不能重写,而isEqual可以根据需要重写。

Guess you like

Origin blog.csdn.net/weixin_50990189/article/details/117485331
ios