一.ARChtml
1.ARC环境下可使用-(void)dealloc{};处理一些事情(好比移除KVO观察),但不要调用[super dealloc];数组
2.ARC与非ARC混编要注意符合Cocoa命名约定,好比不能用copyRight这样的方法名,需改为copyright。或使用NS_RETURNS_RETAINED或NS_RETURNS_NOT_RETAINED告诉编译器使用哪一种内存管理规则,这些修饰符在NSObjCRuntime.h中定义的。安全
3.readonlyString在类扩展部分被从新定义时使用readwrite关键字进行修饰,这样一来便为该属性建立了一个私有的设置方法(setter)。app
@interface ViewController : UIViewController函数
@property (nonatomic, readonly, strong) NSString *readonlyString;atom
@endspa
@interfaceViewController ()线程
@property (nonatomic, readwrite, strong) NSString *readonlyString;code
@endorm
二.属性
1.原子性(atomic),LLVM4中加入了该特性。它本意指属性的存取方法是线程安全的。好比,声明了一个MSMutableArray类型的原子属性stuff,这种状况下self.stuff和self.stuff=otherStuff都是线程安全的。可是,使用objectAtIndex:方法访问数组并非线程安全的,须要用锁来保证线程安全。下面的代码简单表示了atomic的实现:
[_propertyLock lock];
id result = [[value retain] autorelease];
[_propertyLock unlock];
return result;
2.copy,对于非可变类(好比NSString、NSArray)的属性一般应该使用copy修饰。用于声明属性的类可能会拥有可变的子类,好比NSString就可能有一个可变的子类NSMutableString,可以把NSMutableString对象赋给NSString属性,这种状况下你的属性所指向的对象就有可能被其余调用者改变。
@property (nonatomic, copy) NSMutableString *strongStr;
NSMutableString *mString = [[NSMutableStringalloc] initWithFormat:@"mutableString"];
self.strongStr = mString;
NSLog(@"self.strongStr:%@",self.strongStr);
NSLog(@"mString’p:%p",mString);
NSLog(@"self.strongStr’p:%p",self.strongStr);
[mString appendString:@"."];
NSLog(@"self.strongStr:%@",self.strongStr);
NSLog(@"mString’p:%p",mString);
NSLog(@"self.strongStr:%p",self.strongStr);
输出:
2013-06-21 18:08:50.954 PropertyTest[7467:907] self.strongStr:mutableString
2013-06-21 18:08:50.957 PropertyTest[7467:907] mString’p:0x1f592bb0
2013-06-21 18:08:50.959 PropertyTest[7467:907] self.strongStr’p:0x1f592d30
2013-06-21 18:08:50.960 PropertyTest[7467:907] self.strongStr:mutableString
2013-06-21 18:08:50.961 PropertyTest[7467:907] mString’p:0x1f592bb0
2013-06-21 18:08:50.962 PropertyTest[7467:907] self.strongStr’p:0x1f592d30
改成
@property (nonatomic, strong) NSMutableString *strongStr;
输出:
2013-06-21 18:12:35.615 PropertyTest[7505:907] self.strongStr:mutableString
2013-06-21 18:12:35.619 PropertyTest[7505:907] mString’p:0x1e5a7220
2013-06-21 18:12:35.620 PropertyTest[7505:907] self.strongStr’p:0x1e5a7220
2013-06-21 18:12:35.621 PropertyTest[7505:907] self.strongStr:mutableString.
2013-06-21 18:12:35.622 PropertyTest[7505:907] mString’p:0x1e5a7220
2013-06-21 18:12:35.623 PropertyTest[7505:907] self.strongStr:0x1e5a7220
三.+(void)load方法
在第一次加载分类的时候执行。load方法是运行时的一个特性,每个分类均可以实现+load,全部的+load实现都会执行,但执行的顺序是没法保证的。还有,不要尝试手动调用+load。一般在main函数以前(在类被加载到运行时的时候)就被调用。
Foundation Tool示例代码
#import "LoadClass.h"
@implementation LoadClass
+ (void)load
{
NSLog(@"loading ");
}
@end
@implementation LoadClass (category)
+(void)load
{
NSLog(@"Category loading");
}
@end
@implementation LoadClassSubClass
+(void)load
{
NSLog(@"subClass loading");
}
@end
其输出为:
2013-06-24 13:48:42.484 PropertyTest[1340:c07] loading
2013-06-24 13:48:42.489 PropertyTest[1340:c07] subClass loading
2013-06-24 13:48:42.491 PropertyTest[1340:c07] Category loading
+(void)initialize方法
+initialize方法与其余类方法机制相同,这意味着Category中的+initialize方法会覆盖类自己的+initialize方法。而另外一个后果就是,若是父类中实现了+initialize方法,而子类中没有重写此方法,则子类初始化时就会使用父类的方法。这与“每一个类(全部父类和子类)只会执行一次+initialize方法”并不冲突,由于第二次调用父类的+initialize方法是对子类执行,但使用的是同一个方法实现而已。
#import @interface Abstract : NSObject @end @implementation Abstract + (void)initialize { NSLog(@"%@ initialize",self); } @end @interface Sub : Abstract @end @implementation Sub @end int main(int argc, const char * argv[]) { @autoreleasepool { NSLog(@"main Start"); [Sub class]; NSLog(@"Hello, World!"); } return 0; }
其输出为:
main Start Abstract initialize Sub initialize Hello, World!
若是不想子类使用父类的+initialize方法,则父类的+initialize方法能够这样写
+ (void)initialize { if(self == [WhateverClass class]) { ...perform initialization... } }
另一些,不能这样写的情形有: