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

iphone开发Objective-C新特性──类别与协议(转)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文来自:http://blog.csdn.net/pjk1129/article/details/6458644

本文将介绍Objective-C语言的新物性,其中类别(categories)允许在现有的类中添加用户自己的方法,而协议则是Objective-C语言中特有的一种继承方式,类似于java语言中的接口。下面我将首先介绍它们的作用,还将以自己在工程中的实例予以分析。

   一、类别

   有时我们需要在一个已经定义好的类中增加一些方法,而不想去重写该类。比如,当工程已经很大,代码量比较多,或者类中已经包住很多方法,已经有其他代码调用了该类创建对象并使用该类的方法时,可以使用类别对该类扩充新的方法。

  注意:类别只能扩充方法,而不能扩充成员变量。

  实例分析:

  1、目的:在我的工程中,我需要对图片进行压缩,此时我想到类别,利用类别对UIImage类进行扩展,增加图片压缩方法。

  2、类别定义:

类别.h声明文件

#import <Foundation/Foundation.h>

@interface UIImage (UIImageExt)

//这个方法就是我添加的图片压缩的方法

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize;

@end

类别.m实现文件

#import "UIImageExt.h"

@implementation UIImage (UIImageExt)

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize

{

UIImage *sourceImage = self;

UIImage *newImage = nil;

CGSize imageSize = sourceImage.size;

CGFloat width = imageSize.width;

CGFloat height = imageSize.height;

CGFloat targetWidth = targetSize.width;

CGFloat targetHeight = targetSize.height;

CGFloat scaleFactor = 0.0;

CGFloat scaledWidth = targetWidth;

CGFloat scaledHeight = targetHeight;

CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

if (CGSizeEqualToSize(imageSize, targetSize) == NO)

{

CGFloat widthFactor = targetWidth / width;

CGFloat heightFactor = targetHeight / height;

if (widthFactor > heightFactor)

scaleFactor = widthFactor; // scale to fit height

else

scaleFactor = heightFactor; // scale to fit width

scaledWidth= width * scaleFactor;

scaledHeight = height * scaleFactor;

// center the image

if (widthFactor > heightFactor)

{

thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;

}

else if (widthFactor < heightFactor)

{

thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;

}

}

UIGraphicsBeginImageContext(targetSize); // this will crop

CGRect thumbnailRect = CGRectZero;

thumbnailRect.origin = thumbnailPoint;

thumbnailRect.size.width= scaledWidth;

thumbnailRect.size.height = scaledHeight;

[sourceImage drawInRect:thumbnailRect];

newImage = UIGraphicsGetImageFromCurrentImageContext();

if(newImage == nil)

NSLog(@"could not scale image");

//pop the context to get back to the default

UIGraphicsEndImageContext();

return newImage;

}

 

@end

   3、如何使用类别
   在上文我已经对UIImage进行了扩展,下面如何将演示在我的工程中如何调用该方法:

//根据图片tag显示图片

-(void)showPhotoBySerialNumber:(int)imageTag;

{

//这个largeImageArray是NSMutableArray类型的,存放图片存储路径,根据路径得到UIImage

UIImage *img = [UIImageimageWithContentsOfFile:[self.largeImageArrayobjectAtIndex:imageTag]];

//MyScrollView是我自定义的ScrollView,目的是使ScrollView响应点击事件,关于如何自定义的ScrollView在以后的博客中,我将会阐述

MyScrollView *scrView = [[MyScrollView alloc] initWithFrame:CGRectMake(340*imageTag, 0, 320, 480)];

scrView.host = self;

//这句就是调用了类别,通过UIImage实例对象,调用imageByScalingAndCroppingForSize:类别

scrView.image = [img imageByScalingAndCroppingForSize:CGSizeMake(320.0, 480.0)];

scrView.tag = imageTag+100;

//下面这句,就是把上面的scrView塞到imageScrollView上,imageScrollView是UIScrollView类型

[self.imageScrollViewaddSubview:scrView];

[scrView release];

}

    二、协议

   协议(protocol)类似于java语言里的接口(interface),定义了一组方法,而不提供具体实现, 只有那些遵守”(conform to)采用”(adopt)了这些Protocol的类来给出自己的实现。协议不是类本身,它们仅定义了其它对象有责任实现的接口。当在自己的类中实现协议的方法时,用户的类就是遵守这个协议的,协议声明的方法可以被任何一个类实现。

  1、协议的语法结构如下:

  @protocol ProtocolName   //协议名

   methodDeclaration;        //方法名
  @end
  2、如何使用协议
  而在类声明时,语法如下:

  @interface ClassName : ParentClassName < ProtocolName>

 

  然后在该类的实现文件中,实现该协议的方法methodDeclaration

  3、实例分析

  下面以在我的工程项目中协议的使用方法,这里只要讲我自己定义的协议。

  1)该实例的目的:使在ScrollView上面的UIImageView响应点击事件

  2)协议定义:

在类的.h声明文件中定义协议

#import <Foundation/Foundation.h>

//协议ImageTouchDelegate

@protocol ImageTouchDelegate

//协议中声明的方法

-(void)imageTouch:(NSSet *)touches withEvent:(UIEvent *)event whichView:(id)imageView;

@end

@interface ImageTouchView : UIImageView {

id<ImageTouchDelegate>  delegate;

}

@property(nonatomic,assign)id<ImageTouchDelegate> delegate;

@end 

该类的.m实现文件如下

#import "ImageTouchView.h"

@implementation ImageTouchView

@synthesize delegate;

-(id)initWithFrame:(CGRect)frame

{

if (self == [super initWithFrame:frame])

{

[selfsetUserInteractionEnabled:YES];

}

return  self;

}

-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view

{

returnYES;

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

[delegateimageTouch:touches withEvent:event whichView:self];

}

@end

   3)如何使用协议?

   前面我已经定义了ImageTouchDelegate,那么如何使用该协议的方法呢?当某个类要采用该协议时,在类的声明中列出协议的名称即可,如果要采用多个协议时,在后面的尖括号中以逗号分隔,加入即可。当在类采用了该协议时,就要在除了.h文件中进行声明外,还必须在它的.m实现文件中对声明的协议中的方法进行实现。还以上述我们已经定义好的协议为例,演示在我的工程中如何实现该协议。

  在我的类中,首先在.h声明文件中,采用协议ImageTouchDelegate

#import <UIKit/UIKit.h>

//引入定义协议ImageTouchDelegate的头文件

#import "ImageTouchView.h"

//把协议名放到父头后面的尖括号里面,如果有多个协议,用逗号分隔

@interface PhotoOnShotViewController : UIViewController<ImageTouchDelegate> {

 }

@end

  下面要在类的.m实现文件中实现该协议定义的方法

 #import "PhotoOnShotViewController.h"

 @implementation PhotoOnShotViewController

 //实现协议中定义的方法,

-(void)imageTouch:(NSSet *)touches withEvent:(UIEvent *)event whichView:(id)imageView{

 }

@end

   类别与协议在IOS开发中应用很广,也很实用,有必要掌握它们!

   好了,关于类别和协议的简单应用已经叙述完毕,有不到之处欢迎网友指教,希望得到更多的交流!


鲜花

握手

雷人

路过

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

请发表评论

全部评论

专题导读
上一篇:
Objective-C基础8:类扩展(classextension)发布时间:2022-07-12
下一篇:
深入理解Objective-CRuntime发布时间: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