本文將介紹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 = [UIImage imageWithContentsOfFile:[self.largeImageArray objectAtIndex: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.imageScrollView addSubview: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])
{
[self setUserInteractionEnabled:YES];
}
return self;
}
-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
return YES;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[delegate imageTouch: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開發中應用很廣,也很實用,有必要掌握它們!
好了,關於類別和協議的簡單應用已經敘述完畢,有不到之處歡迎網友指教,希望得到更多的交流!
引用:http://blog.csdn.net/pjk1129/article/details/6458644