OC处理对象
Posted Billy Miracle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OC处理对象相关的知识,希望对你有一定的参考价值。
打印对象和description方法
NSLog()函数不仅可以用于输出基本类型的值,也可用于输出OC对象,当使用NSLog()函数输出OC对象时,输出的是该对象的description方法的返回值。也就是说,下面两行代码完全一样:
NSLog(@"%@", p);
NSLog(@"%@", [p description]);
description方法是NSObject类的一个实例方法,所有的OC类都是NSObject类的子类,因此,所有的OC对象都有description方法。
description方法是一个特殊的方法,它是一个“自我描述”方法,该方法通常用于实现这样一个功能:当程序员直接打印该对象时,系统会输出该对象的“自我描述”信息,用以告诉外界该对象具有的状态信息。
NSObject类提供的description方法总是返回<FKPerson: 十六进制的首地址>,这个返回值并不能真正实现“自我描述”功能,因此,用户可以重写NSObject类的description方法。
很多时候,重写description方法可以返回该对象所有令人感兴趣的信息所组成的字符串,格式通常如下:
<类名 [实例变量1 = 值1,实例变量2 = 值2,...]>
示例:
// FKApple.h
#import <Foundation/Foundation.h>
@interface FKApple : NSObject
@property (nonatomic , copy) NSString* color;
@property (nonatomic , assign) double weight;
-(id) initWithColor: (NSString*) color weight: (double) weight;
-(NSString*) description2;
@end
// FKApple.m
#import "FKApple.h"
@implementation FKApple
-(id) initWithColor:(NSString *)color weight:(double)weight {
if(self = [super init]) {
self.color = color;
self.weight = weight;
}
return self;
}
//重写父类的description方法
-(NSString*) description {
//返回一个字符串
return [NSString stringWithFormat:@"<FKApple[_color=%@,_weight=%g]>",self.color,self.weight];
}
//演示父类的description方法
-(NSString*) description2 {
return [super description];
}
@end
// main.m
#import "FKApple.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
FKApple* a = [[FKApple alloc] initWithColor: @"red" weight: 8.6];
NSLog(@"%@", a);
NSLog(@"%@", [a description]);
NSLog(@"%@", [a description2]);
}
return 0;
}
输出结果:
<FKApple[_color=red,_weight=8.6]>
<FKApple[_color=red,_weight=8.6]>
<FKApple: 0x100709ba0>
从上面输出结果可以看出,通过重写FKapple类的description方法,就可以让系统在打印FKapple对象时打印出该对象的“自我描述”信息。
==和isEqual: 方法
OC程序中测试两个变量是否相等有两种方式:一种是利用 == 运算符,另一种是利用 isEqual: 方法。
当使用 == 来判断两个变量是否相等时,如果两个变量是基本类型的变量,且都是数值型,则只要两个变量的值相等,使用 == 判断就将返回真。对于两个指针型变量,它们必须指向同一个对象(两个指针变量保存的地址相同)时,使用 == 判断才会返回真。
示范:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
int it = 65;
float f1 = 60.0f;
char ch = 'A';
NSLog(@"65和65.0f是否相等:%d", (it == f1));
NSLog(@"65和‘A'是否相等:%d", (it == ch));
NSString* str1 = [NSString stringWithFormat:@"我是一个菜鸡"];
NSString* str2 = [NSString stringWithFormat:@"我是一个菜鸡"];
NSLog(@"str1和str2二者地址:%p %p",str1,str2);
NSLog(@"str1 == str2 结果:%d",(str1 == str2));
NSLog(@"str1 isEqual:str2 结果:%d",[str1 isEqual: str2]);
}
return 0;
}
结果:
65和65.0f是否相等:0
65和‘A'是否相等:1
str1和str2二者地址:0x10060e490 0x10060f310
str1 == str2 结果:0
str1 isEqual:str2 结果:1
常量池:
NSString* s1 = @"我是一个菜鸡";
NSString* s2 = @"我是一个菜鸡";
NSString* s3 = [NSString stringWithFormat:@"我是一个菜鸡"];
常量池保证相同的字符串直接量只有一个,不会产生多个副本,例子中的s1、s2都将指向常量池中的同一个字符串对象,因此,s1、s2保存的地址值完全相同。
使用NSString的stringWithFormat: 类方法创建的字符串对象是运行时创建出来的,它被保存在运行时内存区(即堆内存)内,不会放入常量池,所以s3指针变量中保存的地址与s1、s2指针变量中保存的地址并不相同。
重写isEqual: 方法
如果希望采用自定义的相等标准,则可以通过重写isEqual: 方法来实现。
NSString已经重写了NSObject的 isEqual: 方法:NSString的isEqual: 方法判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过 isEqual: 比较就将返回真,否则返回假。
示例:
// FKUser.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface FKUser : NSObject
@property (nonatomic , copy) NSString* name;
@property (nonatomic , copy) NSString* idStr;
-(id) initWithName: (NSString*) name idStr: (NSString*) idStr;
@end
// FKUser.m
#import "FKUser.h"
@implementation FKUser
-(id) initWithName:(NSString *)name idStr:(NSString *)idStr {
if(self = [super init]) {
self.name = name;
self.idStr = idStr;
}
return self;
}
//重写isEqual:方法,提供自定义的相等标准
-(BOOL) isEqual:(id) other {
//如果两个对象为同一个对象
if (self == other) {
return YES;
}
//当other不为nil,且它是FKUser类的实例时
if(other != nil && [other isMemberOfClass: FKUser.class]) {
FKUser* target = (FKUser*) other;
//并且当前对象的idStr与target对象的idStr相等才可判断两个对象相等
return [self.idStr isEqual: target.idStr];
}
return NO;
}
@end
// main.m
#import "FKUser.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
FKUser* p1 = [[FKUser alloc] initWithName: @"Billy" idStr: @"12345123456"];
FKUser* p2 = [[FKUser alloc] initWithName: @"Billie" idStr: @"12345123456"];
FKUser* p3 = [[FKUser alloc] initWithName: @"Peter" idStr: @"12345678911234"];
//p1和p2的idStr相等,输出1
NSLog(@"p1和p2是否相等:%d", [p1 isEqual: p2]);
//p2和p3的idStr不相等,输出0
NSLog(@"p2和p3是否相等:%d", [p2 isEqual: p3]);
}
return 0;
}
通常而言,正确地重写isEqual: 方法应该满足下列条件:
- 自反性:对任意x,[x isEqual: x]一定返回真。
- 对称性:对任意x和y,如果[y isEqual: x]返回真,则[x isEqual: y]也返回真。
- 传递性:对任意x、y、z,如果有[x isEqual: y]返回真,[y isEqual: z]返回真,则[x isEqual: z]一定返回真。
- 一致性:对任意x和y,如果对象中用于比较的关系属性没有改变,那么无论调用[x isEqual: y]多少次,返回的结果都应该保持一致,要么一直是真,要么一直是假。
- 对任何不是nil的x,[x isEqual: nil]一定返回假。
以上是关于OC处理对象的主要内容,如果未能解决你的问题,请参考以下文章