整理一些Objective-c相关知识.
c#与objective-c对照着看,一步一步来.重点在oc上.
1:新建类.
/*C#*/public class Person{private string name;public string GetName(){return name;}public void SetName(string value){name = value;}public static void SayHello(){ /*print hello*/}}
/*o-c*//*.h*/ #import <Foundation/Foundation.h> @interface Person : NSObject {@private NSString *name; }-(NSString *) getName;-(void) setName:(NSString *) value;+(void) sayHello; @end/*.m*/ #import "Person.h"@implementation Person -(NSString *) getName{return name; } -(void) setName:(NSString *) value{if(name != value){[name release];name = [value retain];} } +(void) sayHello{NSLog(@"Hello"); } @end
{...}即是成员变量,也可以使用@private @public @protected
来指定访问级别. 如果不加,默认是protect.方法默认就是public,你在xcode里也@不出来访问修释符.
- 方法前加减号,表示这个方法是对象方法, + 方法前加加号,表示这个方法是类方法, c#同学可以感受下.
2:Two Stage Creation 两段构造模式.
/*C#*/ Person p = new Person(); //创建一个实例
/*oc*/ Person *p = [[Person alloc] init]
oc在构建对象的时候采用的是两段构造. 先调用了(+) alloc方法, 再调用(-) init方法 alloc分配内存空间,init负责初始化值. 再另写一个 对比下.那就秒懂了,其实就这点事.理解很容易.
/*C# 添加构造函数*/ public Person() {} public Person(string name) {
this.name = name;
} /*C# 构建对象*/ Person p = new Person("New Name");
/*oc 这里只写出 .m的实现,*/ -(id) initWithName:(NSString *)value{self = [super init];if(self){[name release];name = [value retain];} return self; }/*oc 构建对象*/ Person p = [[Person alloc] initWithName:@"New Name"];
-(id) 表示返回的是一个指针(不习惯就叫对象吧),self等同于 c#里的 this.
init没啥好说的,深入alloc一点吧.
这里引用http://blog.devtang.com/blog/2013/01/13/two-stage-creation-on-cocoa/该blog的一段文字.
当我们通过alloc或allocWithZone方法创建对象时,cocoa会返回一个未”初使化“过的对象。在这个过程中,cocoa除了上面提到的申请了一块足够大的内存外,还做了以下3件事:
- 将该新对象的引用计数(Retain Count)设置成1。
- 将该新对象的isa成员变量指向它的类对象。
- 将该新对象的所有其它成员变量的值设置成零。(根据成员变量类型,零有可能是指nil或Nil或0.0)
我再贴一段 NSObject.m 里关于 alloc和allocWithZone的实现
+ (id) alloc {return [self allocWithZone: NSDefaultMallocZone()]; } + (id) allocWithZone: (NSZone*)z {return NSAllocateObject (self, 0, z); }/*通过allocWithZone :类方法调用NSAllocateObject 函数分配了对象*/struct obj_layout {NSUInteger retained; }; inline id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone) {int size = 计算容纳对象所需内存大小;id new = NSZoneMalloc(zone,size);memset(new, 0, size);new = (id)&((struct obj_layout *)new)[1]; } /*NSAllocateObject 函数通过调用NSZoneMalloc 函数来分配存放对象所需的内存空间,之后将该内存空间置0,最后返回作为对象而使用的指针。*/
http://book.2cto.com/201305/23851.html 这里是我在网上寻的文章,详细解释了,它在内部是如何执行那三件事的.
关于 new , new 等同于 alloc init 双段构造,唯一缺点就是不能使用带参的构造, 如果new之后调用 initWithName 会出错,所以还是遵循官方约定的,使用双段构造.先写到这.