iOS知识梳理 - Objc语法中值得注意的东西

 约 10 分钟

@关键字

1. 类的声明和实现

@interface@implementation
TODO:分类(category)和扩展(extension)

2. 属性相关

@property@synthesize@dynamic

objc推荐我们通过set/get方法访问对象的属性。很显然,为每一个属性手动添加set/get方法的声明和实现是个性价比很低的重复劳动。因此,objc提供了一些关键字帮助我们简化这一过程。这几个关键字实际上就是这么回事儿。

单独做了总结:Objective-C的@property、@synthesize和@dynamic

3. 前向声明

@class告诉编译器有这么个类在,属性、方法什么的暂时不用管。
主要的好处有两点:

  1. 减少重复编译耗时

    • 当一个头文件发生变化,所有import它的文件都需要重新编译,有些其实是不必要的。
  2. 解决循环引用

相关讨论中可以看到一些建议:

  1. 在.h文件中尽量多地用@class
  2. 在.m文件中全部用import

但就我个人见到的代码而言,@class并不是广泛使用的特性。比起大量使用@class,我更倾向于只在有必要时才使用它。

4. 实例变量可见性

@public:实例变量可使用符号 person->age = 32" 被直接读取。
@package:实例变量是公开的,除非它被指定在框架外(仅适用 64 位架构)
@protected:实例变量仅可由其类和其衍生类访问
@private:实例变量仅可由其类访问

极少显式地使用,用起来是这个样子:

@interface Person : NSObject {
  @public
  NSString name;
  int age;

  @private
  int salary;
}

默认地,@interface里定义的实例变量是@protected的,子类可访问。
需要私有变量时比较常见的方式是通过类扩展定义:

@interface HelloViewController ()
{
     int _value;
}

也可以在@implentation部分定义:

@implementation HelloViewController
{
    int _value;
}

5. 协议

@protocol
协议,也就是在OO中谈论的接口。
在协议中我们可以使用@required 和 @optional来指定方法是否必须实现,默认是required。

@protocol CustomControlDelegate
  - (void)control:(CustomControl *)control didSucceedWithResult:(id)result;
@optional
  - (void)control:(CustomControl *)control didFailWithError:(NSError *)error;
@end

@optionnal这个特性使得代码更加灵活,挺多别的语言并不支持类似的能力,算是OC的一个优点了。

6. 异常处理

try/catch/finally,不赘述。

@try{
  // 试图执行下列语句
  [self getValue:&value error:&error];

  // 如果有异常或者被显式抛出...
  if (error) {
    @throw exception;
  }
} @catch(NSException *e) {
  // …在这里处理异常
}  @finally {
  // 总是在@try或@catch block的尾部执行这个
  [self cleanup];
}

有个很大的项目为了减少安装包大小,曾经把oc exception的能力给关掉了。 = =,不要学他们。

7. 对象字面量

@“aaa”
@100
@YES
@[@"a",@"b",@"c"]
@{
    @"key":@"value"
}

8. OC字面量

  • @selector():返回一个指向有特定名称的选择器的 SEL 指针。用于类似 -performSelector:withObject: 的方法。
  • @protocol():返回一个指向有特定名称的协议的 Protocol * 指针。用于类似 -conformsToProtocol: 的方法。

9. C字面量

@encode():返回一个类型的类型编码。这个类型值可以用于 NSCoder -encodeValueOfObjCType:at 中的第一个参数编码。

char *enc1 = @encode(int);                 // enc1 = "i"
char *enc2 = @encode(id);                  // enc2 = "@"
char *enc3 = @encode(@selector(aMethod));  // enc3 = ":"

@defs():返回一个 Objective-C 类的布局。已废弃。

10. 内存管理

@autoreleasepool

11. 锁

@synchronized()
性能比较差但是用起来最方便的锁。

12. 别名

@compatibility_alias可以给类设置一个别名。

@compatibility_alias UICollectionViewController PSTCollectionViewController;

enum

typedef NS_ENUM(NSUInteger, TTGState) {
    TTGStateOK = 0,
    TTGStateError,
    TTGStateUnknow
};

参考

Enum in OC

空指针

  • NULL:C的空指针 (void *)0
  • nil:objc的空对象 (id)0
  • Nil:空的类指针 (Class)0
  • NSNull:nil的包装类,为了表示dic里面的某个value为空 [NSNull null]

总结:前三个数值上是相等的,在objc中用nil比较普遍

参考nil / Nil / NULL / NSNull

BOOL

常见的就是bool和BOOL。

bool是c语言的,单独的一个类型(_Bool),在数值上true = 1,false = 0

bool类型只有true和false两种状态。

另外,条件判断语句在判断时,是以0为false,非0为true进行判断的。

由此有以下结论:

2 == true //假
(bool)2 == true //真
2 //真

BOOL是ObjC定义的真假值类型,它在64位机器上等价于bool,在32位机器上是signed char

其定义如下,参考objc4-750

/// Type to represent a boolean value.

#if defined(__OBJC_BOOL_IS_BOOL)
    // Honor __OBJC_BOOL_IS_BOOL when available.
#   if __OBJC_BOOL_IS_BOOL
#       define OBJC_BOOL_IS_BOOL 1
#   else
#       define OBJC_BOOL_IS_BOOL 0
#   endif
#else
    // __OBJC_BOOL_IS_BOOL not set.
#   if TARGET_OS_OSX || TARGET_OS_IOSMAC || (TARGET_OS_IOS && !__LP64__ && !__ARM_ARCH_7K)
#      define OBJC_BOOL_IS_BOOL 0
#   else
#      define OBJC_BOOL_IS_BOOL 1
#   endif
#endif

#if OBJC_BOOL_IS_BOOL
    typedef bool BOOL;
#else
#   define OBJC_BOOL_IS_CHAR 1
    typedef signed char BOOL; 
    // BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
    // even if -funsigned-char is used.
#endif

YES和NO

bool的表现已经讲过,这里关注一下BOOL作为signed char的表现。

这时,一个BOOL类型的变量值范围是-128~127,因此强制类型转换时可能会有异常:

BOOL boolVar = 256;
boolVar //假
boolVar == 0 //真

另外强制类型转换时也不会把值转为0和1:

(BOOL)2 == true //假

综上,使用时需注意:

  1. 使用条件表达式时不需要跟YES、NO进行比较,如if(var == YES)应当直接写成if(var)
  2. 不要把其它类型强制转换成BOOL

参考:

  1. ObjC的BOOL为什么要用YES、NO而不建议用true、false?
  2. BOOL / bool / Boolean / NSCFBoolean

category和extension

单独开一篇,见iOS知识梳理 - category和extension

内存管理

TODO:后面总结梳理。

阅读 518

推荐阅读
二师兄的博客
用户专栏

个人博客,希望这次能多写点

3 人关注
39 篇文章
专栏主页
目录