一.
NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续运行,如果返回假值,则抛出异常,并且可以自定义异常描述。
NSAssert()是这样定义的:
#define NSAssert(condition, desc)
condition是条件表达式,值为YES或NO;desc为异常描述,通常为NSString。当conditon为YES时程序继续运行,为NO时,则程序异常抛出带有desc描述的异常信息。NSAssert()可以出现在程序的任何一个位置。
二.
在ios开发过程中,有时候会用到第三方的静态库(.a文件),OC没有为每个函数(或者方法)定义链接符号,它只为每个类创建链接符号。这样当在一个静态库中使用类别来扩展已有类的时候,链接器不知道如何把类原有的方法和类别中的方法整合起来,就会导致你调用类别中的方法时,会出现selector not recognized的错误,从而导致app闪退。使用这段宏定义他可以虚拟新建一个与名字category 相同.h.m 让编译器 编译通过。即可解决上面的问题。
写在.m文件
/**
Add this macro before each category implementation, so we don't have to use
-all_load or -force_load to load object files from static libraries that only
contain categories and no classes.
More info: http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html .
*******************************************************************************
Example:
#import "NSObject+YYAdd.h"
YYSYNTH_DUMMY_CLASS(NSObject_YYAdd)
*/
#ifndef YYSYNTH_DUMMY_CLASS
#define YYSYNTH_DUMMY_CLASS(_name_) \
@interface YYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
@implementation YYSYNTH_DUMMY_CLASS_ ## _name_ @end
#endif
三.关于block,weak&strong
/**
Synthsize a weak or strong reference.
Example:
@weakify(self)
[self doSomething^{
@strongify(self)
if (!self) return;
...
}];
*/
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
四. 实现动态给category 添加属性
具体参见http://www.jianshu.com/p/4a1531bac39f
普及一点宏定义 的关键字 一个# 表示要替换变量 ,两个 ##要拼接字符串 ,\表示多行 cmd 是iOS 是一种特定宏 ,表示本地方法, 在这里表示 @selector(_setter:)
/**
Synthsize a dynamic object property in @implementation scope.
It allows us to add custom properties to existing classes in categories.
@param association ASSIGN / RETAIN / COPY / RETAIN_NONATOMIC / COPY_NONATOMIC
@warning #import <objc/runtime.h>
*******************************************************************************
Example:
@interface NSObject (MyAdd)
@property (nonatomic, retain) UIColor *myColor;
@end
#import <objc/runtime.h>
@implementation NSObject (MyAdd)
YYSYNTH_DYNAMIC_PROPERTY_OBJECT(myColor, setMyColor, RETAIN, UIColor *)
@end
*/
#ifndef YYSYNTH_DYNAMIC_PROPERTY_OBJECT
#define YYSYNTH_DYNAMIC_PROPERTY_OBJECT(_getter_, _setter_, _association_, _type_) \
- (void)_setter_ : (_type_)object { \
[self willChangeValueForKey:@#_getter_]; \
objc_setAssociatedObject(self, _cmd, object, OBJC_ASSOCIATION_ ## _association_); \
[self didChangeValueForKey:@#_getter_]; \
} \
- (_type_)_getter_ { \
return objc_getAssociatedObject(self, @selector(_setter_:)); \
}
#endif
/**
Synthsize a dynamic c type property in @implementation scope.
It allows us to add custom properties to existing classes in categories.
@warning #import <objc/runtime.h>
*******************************************************************************
Example:
@interface NSObject (MyAdd)
@property (nonatomic, retain) CGPoint myPoint;
@end
#import <objc/runtime.h>
@implementation NSObject (MyAdd)
YYSYNTH_DYNAMIC_PROPERTY_CTYPE(myPoint, setMyPoint, CGPoint)
@end
*/
#ifndef YYSYNTH_DYNAMIC_PROPERTY_CTYPE
#define YYSYNTH_DYNAMIC_PROPERTY_CTYPE(_getter_, _setter_, _type_) \
- (void)_setter_ : (_type_)object { \
[self willChangeValueForKey:@#_getter_]; \
NSValue *value = [NSValue value:&object withObjCType:@encode(_type_)]; \
objc_setAssociatedObject(self, _cmd, value, OBJC_ASSOCIATION_RETAIN); \
[self didChangeValueForKey:@#_getter_]; \
} \
- (_type_)_getter_ { \
_type_ cValue = { 0 }; \
NSValue *value = objc_getAssociatedObject(self, @selector(_setter_:)); \
[value getValue:&cValue]; \
return cValue; \
}
#endif
不用宏定义的写法
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface NSObject (Extension)
@property (nonatomic, strong) NSArray *books;
@end
#import "NSObject+Extension.h"
@implementation NSObject (Extension)
-(void)setBooks:(NSArray *)books{
objc_setAssociatedObject(self, @selector(setBooks:), books, OBJC_ASSOCIATION_RETAIN);
}
-(NSArray *)books{
return objc_getAssociatedObject(self, @selector(setBooks:));
}
@end
使用:
#import "NSObject+Extension.h"
@implementation NSObject (Extension)
YYSYNTH_DYNAMIC_PROPERTY_OBJECT(books,setBooks,RETAIN, NSArray *);
@end
五. 写带有返回值的宏定义
/**
Convert CFRange to NSRange
@param range CFRange @return NSRange
*/
static inline NSRange YYNSRangeFromCFRange(CFRange range) {
return NSMakeRange(range.location, range.length);
}