1、@property与@synthesize配对使用。

  • @property预编译指令的作用是自动声明属性的setter和getter方法。
  • @synthesize 创建了该属性的访问代码
  • 功能:让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。

2、强引用(__strong)和 弱引用(__weak)

  • 在Objective-C的ARC模式中,
id obj1 = [[NSObject alloc] init];
  • 这里虽然没有显示的声明为__strong,但是Objective-C默认声明的一个对象就为__strong,即:
id obj1 = [[NSObject alloc] init];
id __strong obj1 = [[NSObject alloc] init];
  • 是等价的。
  • 在强引用中,有时会出现循环引用的情况,这时就需要弱引用来帮忙(__weak)。
  • 强引用持有对象,弱引用不持有对象。
  • 强引用可以释放对象,但弱引用不可以,因为弱引用不持有对象,当弱引用指向一个强引用所持有的对象时,当强引用将对象释放掉后,弱引用会自动的被赋值为nil,即弱引用会自动的指向nil。
  • 下面用代码来说明:
//
// main.m
// ARC中的强引用和弱引用
// #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) {
@autoreleasepool {
id __weak obj0 = nil;
if (YES) {
id obj1 = [[NSObject alloc] init];
obj0 = obj1;
NSLog(@"obj0: %@", obj0);
}
NSLog(@"obj0: %@", obj0);
}
return 0;
} /*
* 输出结果
* obj0: <NSObject: 0x1003066c0>
* obj0: (null)
*
* 因为obj1生成的默认的为强引用(__strong),在超出if的作用域之后,obj1所持有的对象被释放,
* obj0为弱引用,所以obj0不持有对象,在obj1对象释放后,obj0自动的被赋值为nil
* 弱引用的特性是,不持有对象,即便是写成id __weak obj1 = [[NSObject alloc] init];
* 此代码系统会给与警告,因为这里obj1被声明成弱引用,那么在赋值之后,alloc出来的对象会被立即释放。
*/

3、点表达式,可以用来访问对象,类似C语言的结构体访问。

  • 点表达式出现在等号的左边,该变量名称的setter方法将被调用;点表达式出现在等号的右边,该变量名称的getter方法将被调用。

4、什么是Category

  • Category模式用于向已经存在的类添加方法从而达到扩展已有类的目的,在很多情形下Category也是比创建子类更优的选择。

  • 新添加的方法同样也会被被扩展的类的所有子类自动继承。

  • 当知道已有类中某个方法有BUG,但是这个类是以库的形式存在的,我们无法直接修改源代码的时候,Category也可以用于替代这个已有类中某个方法的实体,从而达到修复BUG的目的。

  • 然而却没有什么便捷的途径可以去调用已有类中原有的那个被替换掉方法实体了。

  • 需要注意的是,当准备有Category来替换某一个方法的时候,一定要保证实现原来方法的所有功能,否则这种替代就是没有意义而且会引起新的BUG。

  • 和子类不同的是,Category不能用于向被扩展类添加实例变量。

  • Category通常作为一种组织框架代码的工具来使用。

  • 4.1 Category的用途:

    • 在不创建继承类的情况下实现对已有类的扩展。
    • 简化类的开发工作(当一个类需要多个程序员协同开发的时候,Category可以将同一个类根据用途分别放在不同的源文件中,从而便于程序员独立开发相应的方法集合)。
    • 将常用的相关的方法分组。
    • 在没有源代码的情况下可以用来修复BUG。
  • 4.2 Category的用法

    • 在Obj-C中,声明某一个已有类的Category扩展的方法如下:
    @interface ClassName (CategoryName) 
    
    -methodName1
    -methodName2 @end
    • 上面的声明通常是在.h文件中,然后我们在.m文件中实现这些方法:
    @implementation ClassName (CategoryName) 
    
    -methodName1
    -methodName2 @end
    • 我们创建一个iOS Single View Applciation名为CategoryExample。然后为创建一个NSString类的category扩展。File->New->File然后选择 Cocoa Touch Objective-C category.命名为ReverseNSString.系统会自动生成一个固定格式ClassName+CategoryName的.h和.m文件。
    • 声明Category
      • 打开NSString+ReverseNSString.h文件,在里面添加如下代码:
      #import <Foundation/Foundation.h> 
      
      @interface NSString (ReverseNSString) 
      
      + (NSString*) reverseString:(NSString*)strSrc; 
      
      @end
    • 实现Category
      • NSString+ReverseNSString.m文件中实现reverseString方法:
      #import"NSString+ReverseNSString.h" 
      
      @implementationNSString (ReverseNSString)
      + (NSString*)reverseString:(NSString*)strSrc { NSMutableString *reversedString = [[NSMutableString alloc]init];
      NSInteger charIndex = [strSrc length];
      while (charIndex > 0) {
      charIndex--;
      NSRange subStrRange =NSMakeRange(charIndex, 1);
      [reversedString appendString:[strSrcsubstringWithRange:subStrRange]];
      }
      return reversedString;
      }
      @end
      • 剩下的工作就是验证我们的Category了,在view中添加一个按钮ReverseString,并设置相应的action方法为reverseString.在view上再添加一个label,命名为myString,默认值是”HelloCategory Design Pattern!”。点击按钮反转这个字符串。主要代码如下:
      - (IBAction)reverseString:(id)sender {
      NSString *test = [NSStringreverseString:_myString.text];
      _myString.text = test;
      }
  • 4.3 代码组织

    • Category用于大型类有效分解。通常一个大型类的方法可以根据某种逻辑或是相关性分解为不同的组,一个类的代码量越大,将这个类分解到不同的文件中就显得越有用,每个文件中分别是这个类的某些相关方法的集合。
    • 当有多个开发者共同完成一个项目时,每个人所承担的是单独的cagegory的开发和维护。这样就版本控制就更加简单了,因为开发人员之间的工作冲突更少了。
  • 4.4 Category VS 添加子类

    • 并没有什么界限分明的判定标准来作为何时用Category何时用添加子类的方法的指导。但是有以下几个指导性的建议:

      • 如果需要添加一个新的变量,则需添加子类。
      • 如果只是添加一个新的方法,用Category是比较好的选择。

5、Class Extension(类扩展)

  • class extensions用于解决两个问题:
  • 允许一个对象可以拥有一个私有的interface,且可由编译器验证。
  • 支持一个公有只读,私有可写的属性。
  • 若要定义私有函数,通常是在实现文件中声明一个"Private" category:
@interface MyClass (Private)
- (id)awesomePrivateMethod;
@end
  • 然而, 类的私用方法通常是希望实现在类的@implementation块中的,而不是像上面的Category的方法那样实现在独立的@implementation区块中。事实上,Category仅仅是弥补了Objective-C缺少public/private限定的不足。
  • 真正的问题是Objective-C编译器会认为在Category中声明的方法将会在别处实现,所以编译器并不会尝试确认它们是不是真得都被实现了。也就是说,开发者声明的方法有可能并未实现,而且编译器也不会有什么警告。编译会以为它们将在别的地方或独立的文件中实现。
  • 使用class exteionsion,在其中声明的方法和属性的实现将放在class的@implementation区块中。否则,编译器就会报错。
// someClass.m

@interface someClass ()

-(void)extend;

@end

@implementation someClass

// 所有声明在头文件或父类中方法的实现
// 或者一些私有函数
-(void)extend {
// implement private method here;
} @end
  • 公有可读、私有可写的属性(Publicly-Readable, Privately-Writeable Properties)
  • 实现一个不可变(immutable)的数据结构通常有一个好处是外部代码不能用setter修改对象的状态。然而,可能又希望它在内部又是一个可写的属性。Class extensions可以做到这一点:在公共接口(类的声明中)中,开发者可以声明一个属性是只读的,随后在类扩展中声明为可写。这样,对外部代码而言,该属性将是只读的,而内部代码却可以使用它setter方法。
@interface MyClass : NSObject 

@property (retain, readonly) float value; 

@end 

// 私有的extension, 隐藏在主实现文件中.
@interface MyClass () @property (retain, readwrite) float value; @end

6、判断对象类型

  • 对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。
  • **-(BOOL) isKindOfClass: classObj **判断是否是这个类或者这个类的子类的实例
  • **-(BOOL) isMemberOfClass: classObj **判断是否是这个类的实例

7、尖括号的含义

  • 声明语句后面的尖括号内的内容标识遵守的协议的名称,如果协议有多个,则在尖括号内部以逗号分隔列出来。

8、self和self class指针的区别

  • self是实例的指针,[self class]是类的指针,静态方法得用类的指针来调用

9、@optional和@required

  • 如果指定的关键字@required,则该方法是必须实现的,如果指定了@optional,该方法不是必须实现。

Object C语法学习笔记(二)的更多相关文章

  1. Html 语法学习笔记二

    1.图像标签(<img>)和源属性(Src) 在 HTML 中.图像由 <img> 标签定义.        <img> 是空标签,意思是说,它仅仅包括属性,而且没 ...

  2. Object C语法学习笔记(一)

    1.@property与@synthesize配对使用. @property预编译指令的作用是自动声明属性的setter和getter方法. @synthesize 创建了该属性的访问代码 功能:让编 ...

  3. Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...

  4. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  5. 毕业设计 之 五 PHP语法学习笔记

    毕业设计 之 四 PHP语法学习笔记 作者:20135216 平台:windows10 软件:XAMPP,DreamWeaver 说明:该笔记是对网站编程语言的详细学习 一.PHP基础 0. 关于环境 ...

  6. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  7. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  8. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  9. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

随机推荐

  1. MFC学习(六)计算器

    1 stdafx.h  所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H.Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使 ...

  2. Ceph recover的速度控制

    前言 磁盘损坏对于一个大集群来说,可以说是必然发生的事情,即使再小的概率,磁盘量上去,总会坏那么几块盘,这个时候就会触发内部的修复过程,修复就是让不满足副本要求的PG,恢复到满足的情况 一般是踢掉坏盘 ...

  3. Linux性能监测:磁盘IO篇

    磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴.寻轨等.访问硬盘和访问内存之间的速度差别是以数量级来计算的,就 ...

  4. [原创]Spring JdbcTemplate 使用总结与经验分享

    引言 近期开发的几个项目,均是基于Spring boot框架的web后端项目,使用JdbcTemplate执行数据库操作,实际开发过程中,掌握了一些有效的开发经验,踩过一些坑,在此做个记录及总结,与各 ...

  5. ubuntu 12.04的源更新

    apt-get install vim 安装vim vim /etc/apt/sources.list deb http://mirrors.163.com/ubuntu/ precise main ...

  6. delphi 在桌面屏幕上模拟鼠标单击

    delphi 在桌面屏幕上模拟鼠标单击 procedure TFrmUnicom.Button1Click(Sender: TObject); var oldPoint, newPoint: TPoi ...

  7. ocx控件针对网页刷新和关闭分别进行区分处理

    当ocx加载在网页上时,如果对网页执行F5刷新事件,ocx控件会销毁ocx的窗口类,但是ocx的APP类是不会销毁的. 只有当网页被关闭时,才销毁app类. --------------------- ...

  8. Spring Cloud Zuul 2(基于配置中心的动态API网关)

    在大体了解了API Zuul 和 配置中心Config后我们来尝试完成一个基于配置中心的动态API网关 创建项目 命名为api-gateway-dynamic-route并加入config 和 Zuu ...

  9. Idea搭建Scala开发环境的注意事项

    Idea搭建Scala开发环境的注意事项 1.下载ideaIC-2017.3.tar.gz 2.解压安装idea 3.File->setting->plugins 下载2个插件scala. ...

  10. 张超超OC基础回顾01_类的创建,申明属性,以及本质

    一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...