整理一些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 会出错,所以还是遵循官方约定的,使用双段构造.先写到这.