OC基础语法(四)---核心语法(2)




一、类的深入研究

类的本质:类本身也是一个对象,是个Class类型的对象,简称类对象。

(类名就是类对象,每个类只有一个类对象)。

Class类型的定义:

Typedef struct objc_class *Class;

Class 创建 Person类对象;

利用Person类对象,创建Person类型对象。

获取内存中的类对象:

Class c1 = [p class];

Class c2 = [p class];

Class c3 = [Person class];

NSLog(@"c1=%p,c2=%p,c3=%p",c1,c2,c3);

c1和c2还有c3地址相同。

总结:获取内存中的类对象有2种方法:

1.通过某个对象的class方法;

2.通过类的class方法。  

                      

二、类的加载和初始

+load和 +initialize

1.+load:

本类被加载的时候调用(类只加载一次);

当程序启动时,就会加载一次项目中的所有的类,类加载完毕后就会调用+load方法.

+ (void)load

{

    NSLog(@"类名......load");

}

2.+initialize:

当第一次使用这个类时,就会调用一次initialize。

+ (void)initialize

{

     NSLog(@"类名......initialize");

}

总结:

1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只调用一次;

2.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load 方法);

3.先加载原来的类,再加载分类;

4.不管程序运行过程中有没有用到这个类,都会调用+load加载;

5.当第一次使用某个类时,就会调用当前的类的+initialize方法,

      先初始化父类,再初始化子类,即先调用父类的+initialize方法,再调   

      用子类的+initialize方法;

6.若分类也有+initialize方法,只会调用分类的+initialize方法,不会

      调用原来的类的+initia。


三、Description(类似于java toSring方法)

例子:默认情况下,利用NSLog 和 %@ 输出对象时,

          结果是:<类名:  内存地址> 

          NSLog(@"%@",p);

分析过程:

1.会调用对象p的 - description方法;

2.拿到- description方法的返回值(NSString *)显示在屏幕上;

3.- description 方法默认返回的是: <类名 内存地址>。

修改 - description 输出对象内容(决定了实例对象的输出结果):

- (NSString *)description

{

    Return 

    [NSString stringWithFormat:@"age = %d,name = %@",_age,_name];

}

此时,调用

 NSLog(@"%@",p);

会输出例如这个结果:age = 15,name = "rose"

注意:一下这种使用会引发死循环

- (NSString *)description

{

     NSLog(@"%@",self);

}

利用NSLog 和 %@ 输出类对象:

Class c = [Person class];

NSLog(@"%@",c);

输出结果:Person(类名)

分析过程:

1.会调用类的+description方法;

2.拿到+description方法返回值(NSSring *)显示在屏幕上。

例子:决定了类对象的输出结果:

+ (NSString *)description

{

   // NSLog(@"%@",@"ABC");

   return @"ABC" 

}

注意:死循环陷阱

      如果在 - description方法中使用NSLog打印self。


四、NSLog输出补充

指针变量地址:

NSLog(@"%p",&p);

对象的地址:

NSLog(@"%p",p);

<类名: 对象地址>:

NSLog(@"%@",p);

输出当前的函数名:

NSLog(@"%s\n",_func_);

输出行号:

NSLog(@"%d",_LINE_);

输出源文件的名称:

NSLog(@"%s",_FILE_);//NSLog输出c语言字符串时,不能有中文


五、SEL类型数据

    SEL类型的定义:

typedef struct objc_selector *SEL;

例子:在内存中

      SEL s1 == - test地址;

      SEL s2 == - test2地址;

      [p test2];


分析:

1.把test2包装成SEL类型的数据;

2.根据SEL数据找到相应的方法地址;

3.根据方法地址调用相应的方法;

间接调用test2方法:

[p performSelector:@selector(test2)];

例如: - (void)test3:(NSString *)abc

       {

            NSLog(@"调用了test3.....%@",abc);

        }

       也可这样调用test3

        [p performSelector:@selector(test3:)withObject:@"456"];


方法的存储位置:

1.每个方法列表都存储在类对象中;

2.每个方法都有一个与之对应的SEL类型的对象;

3.根据一个SEL对象就可以找到方法的地址,进而调用调用方法。


SEL对象的创建:

SEL s = @selector(test3:);

调用test3方法:

[p performSelector:s withObject:@"456"];

把字符串对象转成SEL数据:

NSString *name = @"test2";

SEL s  = NSSelectorFormString(name);

[p performSelector:s];

把SEL对象转NSString对象:

- (void)test

{

    //_cmd代表着当前方法

    NSString *str = NSStringFronSelector(_cmd);

    NSLog(@"调用了方法test......%@",str);

}

[p test];

结果:调用了方法test.....test

注意:以下的代码会引发死循环

- (void)test

{

    [self performSelector:self];

}


总结:SEL其实是对方法的一种包装,将方法包装成一个SEL数据,去找相应的方法地址,找到方法地址就可以调用方法。其实消息就是SEL。


六、练习

比较两个圆是否重叠:

/*

设计一个类Point2D用来表示二维平面中某个点

1.属性

* double x

* double y

2. 方法

属性相应的set方法和get方法

设计一个对象方法同时设置xy

设计一个对象方法计算跟其他点的距离

设计一个类方法计算两个点之间的距离

3. 提示

* C语言中的math.h中有个函数:double pow(double n,double m);计算nm次方

* C语言的math.h中有个函数:double sqrt(double n);计算根号n的值(对n进行开根)

4. 设计一个圆的类Circle

*/

i#import <Foundation/Foundation.h>

#import <math.h>

//

@interface Point2D : NSobject

{  

  double _x;  // x

  double _y; // y

}

  

//设置xsettergetter

-void)setX:(double)x;

- (double)x;

//设置ysettergetter

- (void)setY:(double)y;

- (double)y;

//同时设置xy

- (void)setX:(double)x andY:(double)y;

//计算跟其他点的距离

- (double)distanceWithOther:(Point2D *)other;

//计算两个点之间的距离

+ (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point *)p2;

@end

@implementation Point2D

-void)setX:(double)x

{

   _x = x;

}

- (double)x

{

   return _x;

}

- (void)setY:(double)y

{

   _y = y;

}

- (double)y

{

   return _y;

}

//同时设置xy

- (void)setX:(double)x andY:(double)y;

{

/*

  _x = x;

  _y = y;

*/

  [self setX:x];

  [self setY:y];

 }

//计算跟其他点的距离

- (double)distanceWithOther:(Point2D *)other

{

//((x1-x2)的平方+y1-y2)的平方)开根

  double xDelta = [self x] - [other x];//_x - [other x];

  double yDelta = [self y] - [other y];//_y - [other y];

  double xDeltaPF = pow(xDelta, 2);

  double yDeltaPF = pow(yDelta, 2);

  return sqrt(xDelta + yDelta);

     

}

//计算两个点之间的距离

+ (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point *)p2

{

   return [p1 distanceWithOther:p2];

}

@end

@interface Circle : NSobject

{

   double _radius; // 半径

   Point *_point; // 圆心(组合)

}

//设置半径的settergetter

- (void)setRadius:(double)radius;

- (double)radius;

//设置圆心的settergetter

- (void)setPoint:(Point *)point;

- (void)point;

//判断跟其他圆是否重叠

//返回值是BOOL类型的,方法名一般是以is 开头

- (BOOL)isOverlappingWithOther:(Circle *)other;

+ (BOOL)isOverlappingBetweenCircle1:(Circle *)circle1 andCircle2:(Circle *)circle2;

@end

@implementation Circle

//设置半径的settergetter

- (void)setRadius:(double)radius

{

    _radius = radius;

}

- (double)radius

{

    return _radius;

}

//设置圆心的settergetter

- (void)setPoint:(Point *)point

{

  _point = point; 

}

- (Point *)point

{

   return point;

}

//圆心之间的距离半径之和则不重叠返回NO

//圆心之间的距离半径之和则重叠 返回YES

- (BOOL)isOverlappingWithOther:(Circle *)other

{

    Point *p1 = [self point];

    Point *p2 = [other point];

    double distance = [p1 distanceWithOther:p2;

    double sumRadius = [self radius] - [other radius];

    return distance < sumRadius;

 

}

+ (BOOL)isOverlappingBetweenCircle1:(Circle *)c1 andCircle2:(Circle *)c2

{

            return [c1 isOverlappingWithOther:c2];

@end

int main()

{

/*

  Point *p1 = [Point new];//创建一个新的对象p1

  

  //设置xy的值

  [p1 setX:10 andY:15]; 

  Point *p2 = [Point new];// 创建一个新的对象p2

  

  //设置xy的值

  [p2 setX:13 andY:19];

  //计算p1p2之间的距离

  double d = [p1 distanceWithOther:p2];

  NSLog(@"%d",d);

//调用类方法,计算p1p2之间的距离

  double d2 = [Point distanceBetweenPoint1:p1 andPoint2:p2];

  NSLog(@"%d",d2); 

 */

//创建一个圆的对象

  Circle *c1 = [Circle new];

   

 // 设置圆的半径

 [c setRadius:3];

 //创建圆心的对象

 Point *p1 = [Point new];

 //设置xy的值

 [p1 setX:10 andY:15];

 [c1 setPoint:p1];

//设置一个圆的对象c2

 Circle *c2 = [Circle new];

 

 //设置c2的半径

 [c2 setRadius:5];

 Point *p2 = [Point new];

 [p2 setX:13 andY:19];

 [c2 setPoint:p2];

 BOOL b1 = [c1 isOverlappingWithOther:c2];

 NSLog(@"%d"b1);

}

NSString 分类写个类方法,输出一个字符串中数字的个数:

/*

NSString添加一个类方法,计算字符串中数字的个数

*/

#import <Foundation/Foundation.h>

//#import <NSString+Number>,多文件开发时.m文件的头文件

@interface NSString(Number)

//方法的声明

+ (int)numberOfString:(NSString *)str;

@end

@implementation NSString(Number)

//方法的实现

+ (int)numberOfString:(NSString *)str

{

int count = 0;

for(int i = 0;i < str.length;i++)

{   

//返回第i个位置的字符

unichar c= [str characterAtIndex:i];

//注意字符串是由字符构成的,单个字符要用''包住

if(c >= '0' && c <= '9')

{

count++;

}

}

return count

}

@end

int main()

//NSString 类调用方法

int count = [NSString numberOfString:@"wo shi 123 wang"];

//输出数字的个数

NSLog(@"%d",count);

return 0;

}

运行结果:3

NSString增加一个对象方法,计算当前对象里面的阿拉伯数字的个数:

/*

NSString 添加一个对象方法,计算当前对象里面的阿拉伯数字的个数

*'/

#import <Foundation/Foundation.h>

@interface NSString 

  //方法的声明

  - (int)numberCount;

@end

@implementation NSString

//方法的实现

  - (int)numberCount

  {

      int count = 0;

  for(int i = 0;i <self.length;i++)

  {

    unichar c = [self characterAtIndex:i];

    if(c >= '0' && c <= '9')

    {

   count++;

    }

      }

  return count;

  }

@end

int main()

{

   NSString *str = @"woshi123wang";

   int count = [str numberCount];

   NSLog(@"%d",count);

   return 0;

}

运行结果:3



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值