• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Objective-C语言精要

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
    声明:本人学习Objective-C也才一个多月,下面这些只是自己的理解,不能保证没有理解偏差或错误的地方,如遇高手发现不对的地方,请赐教!
1。我们从最简单的程序Hello World开始:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
}
   #import的功能与C/C++里的#include类似,都是导入头文件。和C/C++程序一样Objective-C里面main()函数也是所有程序的入口,NSAutoreleasePool到后面介绍内存管理时再说!NSLog()的功能与C/C++中printf()函数功能相似,用于输出,只不过在输出时要加@符号。
2。定义类
   在Objective-C中,代码通常放在两种不同的文件中,.h文件与.m文件,在定义一个类时,我们将接口部分interface放在.h文件中,把实现部分implementation放在.m文件中,如下面定义一个学生类:
StudentInfo.h文件
#import <Foundation/Foundation.h>
@interface StudentInfo : NSObject
{
int stuID;
NSString *stuName;
int age;
NSString *place;
}
- (id) initWithID:(int) _ID Name:(NSString *) _name Age:(int) _age Place:(NSString *) _place;
@property (nonatomic ,readwrite) int stuID;
@property (nonatomic ,readwrite) int age;
@property (nonatomic ,retain) NSString *stuName;
@property (nonatomic ,retain) NSString *place;
@end
下面我们重点解释这段代码:
   在Objective-C中,关键字为了和c/c++区分,前面都加了个@符号,在StudentInfo.h文件中,@interface为接口部分,它是以@end结束,这点与C/C++中不同,在C/C++中函数或类都是以{}为始终。@interface StudentInfo : NSObject是定义StudentInfo类的声明部分,该类是继承与NSObject这个父类。其实在Objective-C中,几乎所有的类都是继承于NSObject,也就是NSObject是这些类的根类。说到继承,有一点与C++不同,那就是Objective-C中支持单继承。
   接下来看,在Objective-C里面仍然支持C里面常见的数据类型,如int,char,float,double等,但Objective-C也有一些属于自己的数据类型,或着叫做对象,如NSString,NSArray,NSDictionary等以NS开头的。先只说NSString,NSString *stuName;声明了一个字符串对象stuName,可能你会把它理解成一个指针,不过这样理解也说得通。{}内部的我们把它叫做实例变量,在下面我们只定义了一个方法,用于初始化学生类
-(id)initWithID:(int) _ID Name:(NSString *)_name Age:(int)_age Place:(NSString *) _place
或许你会认为这种定义方式很奇怪,但是仔细理解你会发现这种方式的好处,其实它的作用就是传入4个参数,等价与-(id)initWithStudent::::,这种形式你在C/C++里面定义函数时遇到过吧?Objective-C只是用不同的名字来标识各个变量(或参数),以便你不会将各个参数的意义搞混淆。
@property属性是C/C++里面没有的东西,允许我们自动生成访问器,这里不展开(或许以后会来个专题!),@end接口部分定义完成。
StudentInfo.m文件
#import "StudentInfo.h"
@implementation StudentInfo
@synthesize stuID, stuName, age, place;
- (id) initWithID:(int)_ID Name:(NSString *)_name Age:(int)_age Place:(NSString *)_place
{
if (self = [super init]) {
stuID = _ID;
stuName = [_name retain];
age = _age;
place = [_place retain];
}
return self;
}
@end
   我们在来看实现部分implenmentation,@synthesize叫作合成器,通常与@property一起使用,这也是C/C++里面没有的,暂时不讲。直接看刚才定义的初始化方法的实现,这可以与函数的实现对应起来。self相当于C里面的this指针,停一停,我们先说说消息,在Objective-C里,可以给任意的对象发送消息,发送形式为:[receiver massage];其中receiver为接受消息的对象,massage为要发送的消息,如[super init];其中super是每个当前对象的父类,self为当前对象,if(self = [super init]){}就是当当前对象创建成功,下面给每个实例变量赋值。stuName = [_name retain];的作用是将stuName指向_name所指向的地址,然后将_name指针释放。同时stuName的引用计数加1。引用计数是系统为每个对象生成的一个参数retainCount,当进行copy,alloc,retain,new时,该对象的引用计数会加1,这时当对象使用完后需要将对象释放release,以便合理的管理内存。return self是最后返回对象本身,在Objective-C里面,对象也可以和基本的数据类型一样被引用或打印出来。
   这里一个StudentInfo类就定义完成。我们可以在main()函数中使用它:
#import <Foundation/Foundation.h>
#import "StudentInfo.h"
int main(int argc, char *argv[]) 
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
StudentInfo *stu1 = [[StudentInfo alloc] initWithID:1001 Name:@"张飞" Age:22 Place:@"蜀汉"];
NSLog(@"ID:%d, Name:%@, Age:%d, Place:%@",stu1.stuID,stu1.stuName,stu1.age,stu1.place);
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}
打印出来的结果为:ID:1001, Name:张飞, Age:22, Place:蜀汉
3。访问器Getter和Setter
   在Objective-C里面,大多时候应该使用访问器来获取和设置变量的值,下面我们来看看访问器实际实现的代码:
- (void) setStuID:(int) newID
{
     if (stuID != newID)
          stuID = [newID copy];
}
- (int) stuID
{
     return stuID;
}
  其实在Objective-C里大多时候我们使用getter方法是直接用变量名,而不再用getStuI,这些代码需要我们自己来写吗?其实不用,前面提到属性@property就是让系统为我们自动生成访问器的,因为我们在StudentInfo类里面使用了自动生产访问起的属性,因此我们通过[stu1 setStuName:@”关羽”];就可以把1001号学生姓名改成关羽。通过[stu1 place];就能获得stu1的place值,相当于stu1.place。使用了属性后,点语法一样可以用,至于点语法的使用,大家应该在C/C++里面用的很多,就不介绍了,不过还是推荐在Objective-C里面使用访问器!
4。分类Category和协议Protocol
    这两个也是新概念,它们都是Objective-C里面提供的让你扩展类的定义的方法,其实分类Category为已知类增加新的方法,协议Protocol是声明一些方法,但是让别的类来实现。注意分类和协议只能够增加类的方法,不能用于增加实力变量。
    通过定义分类,你可以为已知的类增加新的方法,哪怕是你不知道原类的代码。你还可以使用分类将你自己的类的定义分开放在不同的源文件里,通常使用分类时的源文件命名为ClassName+CategoryName的形式:
StudentInfo+Category.h文件
#import <Foundation/Foundation.h>
#import "StudentInfo.h"
@interface StudentInfo (Category)
- (void) sayHello;
@end
studentInfo+Category.m文件
#import "StudentInfo+Category.h"
@implementation StudentInfo (Category)
- (void) sayHello
{
NSLog(@"Hello, I'm %@ !",stuName);
}
@end
这个简单的分类为StudentInfo类增加了一个sayHello方法,现在你可以像使用StudentInfo自己的方法一样使用sayHello。
    协议是多个类共享的一个方法列表,用于声明专门被别的类实现的方法,所以协议没用.m文件,只有.h文件用于列出已经存在的方法,如
Protocol.h文件
#import <UIKit/UIKit.h>
@protocol Protocol
@required
- (void) display;
@end
当然这里的display方法需要在某个.m文件中实现,这里我们可以把它放在StudentInfo.m里面(如果你已经在以前的某个文件中定义过这个方法就直接可以用了)
- (void) display
{
NSLog(@"ID:%d, Name:%@, Age:%d, Place:%@",stuID,stuName,age,place);
}
  这样还没完啊,你还要让StudentInfo知道这个协议,把studentInfo.h中增加(修改)成下面这段代码:
#import "Protocol.h"
@interface StudentInfo : NSObject <Protocol>{}  
  协议怎么用?很简单,直接当自己的方法用,当然你还可以通过  
if ([stu1 conformsToProtocol:@protocol(Protocol)]) { }来判定一个对象是否遵循某个协议。
    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
用Objective-C实现的Rc4加密算法发布时间:2022-07-12
下一篇:
Objective-C内存管理(中)发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap