类目、延展、协议
@class 類名; //編譯時只有這個類(不包括該類的變量、方法),加快編譯。常用于復合對象和循環依賴問題中。#import、#include和@class的區別:http://blog.sina.com.cn/s/blog_71715bf80101a8t8.html
id <協議名> _delegate;//代理(實現協議的對象)。
類目、延展、協議都是針對方法。
----------------------------------------------------------------------------------------------------------------------------
類目(Category)
1.作用:為已有的類(有沒有源碼的類都可以,包括系統類)添加方法
2.格式:類似于類
- 聲明部分:沒有繼承,后加上(類目名)
- 實現部分:后加上(類目名)
- 文件名:類名+類目名
3.在類目中self的作用是訪問設置變量,方法.
4.類目用處:
- 擴展別人的類
- 類目把代碼放到多個文件中,便于多人開發,當然也會降低性能.
5.注意
- 類目只能給已有的類添加多個方法,無法添加實例變量,此時可以通過字典類型的參數解決。
- 類目的方法和已有類的方法名稱沖突時,類目中的方法會覆蓋原有的方法。
- 通過類目給一個新類添加新方法來擴展這個類不僅影響這個類,同時會影響他的子類,因為他的每個子類都將繼承這些新方法。若為NSObject添加類目(即非正式協議)。
----------------------------------------------------------------------------------------------------------------------------
延展(extension)
1.作用:定義私有方法.
2.實現延展的形式
- 延展形式1:編寫(聲明)在類的實現文件,定義的方法在類中實現.
- 延展形式2:在自己類的實現文件中添加私有類目來聲明私有方法。(延展只有一個.h文件)
- 延展形式3:新語法最常用,方法不在.h頭文件聲明,直接在.m定義這個方法,相當于私有方法。
3.延展可以定義成員變量,只供類里使用.
----------------------------------------------------------------------------------------------------------------------------
協議(protocol):規定一套標準
一.
?
二.確認協議(相當于簽字)
三.
四.協議特點
五.代理模式
六.
委托和委托方雙方的property聲明屬性都是assign而不是retain
為了避免循環引用造成的內存泄露。
循環引用的問題這樣理解:
比如在main函數中創建了兩個類的對象A和B,現在引用計數都是1?,F在讓A和B互相引用(A有一個屬性是B對象,屬性說明是retain;B有一個屬性是A對象,屬性說明是retain),現在兩個對象的引用計數都增加了1,都變成了2。
現在執行[A release]; [B release]; 此時創建對象的main函數已經釋放了自己對對象的所有權,但是此時A和B的引用計數都還是1,因為他們互相引用了。
這時你發現A和B將無法釋放,因為要想釋放A必須先釋放B,在B的dealloc方法中再釋放A。同理,要想釋放B必須先釋放A,在A的dealloc方法中再釋放B。所以這兩個對象將一直存在在內存中而不釋放。這就是所謂的循環引用的問題。
要想解決這個問題,一般的方法可以將引用的屬性設置為assign,而不是retain來處理。
七.
@class @class就是告訴編譯器有這個類存在,但是類是如何實現的不用告訴編譯器.若.m文件用到了這個類,還是要在.m文件匯總import這個類的。 既然這樣,為什么不直接在頭文件中import呢,舉個例子: class A引用了class B,class B引用了class C.... , class A,B,C...的頭文件又import了很多文件,那么 import了A的話,編譯器就需要編譯大量的文件,編譯時間就會增加。? 難道頭文件中都是用@class嗎?當然不是,有時也是需要#import的,那么什么時候該用什么呢? (1)一般如果有繼承關系的用#import,如B是A的子類那么在B中聲明A時用#import; (2) 另外就是如果有循環依賴關系,如:A->B,B->A這樣相互依賴時,如果在兩個文件的頭文件中用#import分別聲明對方,那么就會出現頭文件循環利用的錯誤,這時在頭文件中用@class聲明就不會出錯; (3)還有就是自定義代理的時候,如果在頭文件中想聲明代理的話如@interface SecondViewController:UIViewController時應用#import不然的話會出錯誤,注意XXXXDelegate是自定義的。----------------------------------------------------------------------------------------------------------------------------
類目
NSString+SayHi.h
#import <Foundation/Foundation.h>@interface NSString (SayHi)//@property(nonatomic,retain)NSString *name;-(void)sayHi; @endNSString+SayHi.m
#import "NSString+SayHi.h"@implementation NSString (SayHi)//@dynamic name;? -(void)sayHi {[self stringByAppendingFormat:@" and bill"];NSLog(@"%@ hello world",self); } @endNSMutableArray+Revert.h
#import <Foundation/Foundation.h>@interface NSMutableArray (Revert) -(void)revert; @endNSMutableArray+Revert.m
#import "NSMutableArray+Revert.h"@implementation NSMutableArray (Revert) -(void)revert {int count = self.count;for ( int i = 0; i < count/2; i++){[self exchangeObjectAtIndex:i withObjectAtIndex:count-i-1];} } @end延展
Teacher.h
#import <Foundation/Foundation.h>@interface Teacher : NSObject-(void)onClass:(NSString *)aClassName;@endTeacher.m
#import "Teacher.h" /* //聲明定義私有方法 @interface Teacher () {NSString *_name; } @property(nonatomic,retain)NSString *name; -(void)prepareClass:(NSString *)aClassName; @end */@implementation Teacher //@synthesize name = _name;-(void)prepareClass:(NSString *)aClassName//5.0+新語法,.h沒聲明的方法就是私有方法 {//備課NSLog(@"prepare Class %@",aClassName); }-(void)onClass:(NSString *)aClassName {//self.name = @"jobs";//對類里//備課//[self prepareClass:aClassName];//上課//NSLog(@"%@ teaching %@",self.name,aClassName);NSLog(@"teaching %@",aClassName); }@endTeacher_PrivateClass.h
#import "Teacher.h"@interface Teacher () -(void)privateMethod; @end?AppDelegate.m
NSString *str = @"jobs";[str sayHi];//str.name = @"bill"; NSArray *arr = @[@"1",@"2",@"3",@"4"];//ios5.0+出新語法NSMutableArray *marr = [NSMutableArray arrayWithArray:arr];[marr revert];//倒置NSLog(@"mArr = %@",marr);//數組輸出是(),字典是{},set是{()}//延展Teacher *t = [[Teacher alloc]init];[t onClass:@"ios"];//[t prepareClass:@"html"];不能調用私有方法//ios早些版本是可以執行.說明沒有私有方法,屬于偽私有?----------------------------------------------------------------------------------------------------------------------------
協議2
RentDelegate.h
/*@overview:學生定義的租房協議@autuor:huen@time:2014-2-10協議不承載信息(成員變量)*/#import <Foundation/Foundation.h>@protocol RentDelegate <NSObject>//遵循于NSObject協議,相當現實于協議再引進其他協議 @required -(void)findHouse:(NSString *)aHouse//參數即房子條件信息,幾居幾錢,代理傳值withMoney:(int)aMoney;@optional//可選 -(BOOL)hasNewHouse;@endStudent.h
#import <Foundation/Foundation.h> #import "RentDelegate.h"@interface Student : NSObject {NSString *_name; } @property(nonatomic,assign)id<RentDelegate> delegate; @property(nonatomic,retain)NSString *name; //租房 -(void)rentHouse; @endStudent.m
#import "Student.h"@implementation Student @synthesize name = _name,delegate = _delegate;//租房 -(void)rentHouse {//讓中介幫助學生找房if ([self.delegate conformsToProtocol:@protocol(RentDelegate)]){[self.delegate findHouse:@"one big" withMoney:1000]; //代理傳值,將學生資源傳給代理 }//中介推薦租房信息if ([self.delegate conformsToProtocol:@protocol(RentDelegate)]){if ([self.delegate respondsToSelector:@selector(hasNewHouse)]){[self.delegate hasNewHouse];}} }@endMediator.h
import <Foundation/Foundation.h> #import "RentDelegate.h" @interface Mediator : NSObject <RentDelegate> {NSString *_name; } @property(nonatomic,retain)NSString *name;@endMediator.m
#import "Mediator.h"@implementation Mediator @synthesize name = _name;//收集房源 -(int)collectHouses {return 5; }#pragma mark -RentDelegate- //實現協議中方法 -(void)findHouse:(NSString *)aHouse withMoney:(int)aMoney {if ([self collectHouses] <= 0){return;}NSLog(@"%@ has found %@ house with %d money",self.name,aHouse,aMoney); }-(BOOL)hasNewHouse {NSLog(@"has new house");return YES; } @endAppDelegate.m
Mediator *m = [[Mediator alloc]init];m.name = @"jobs";Student *s = [[Student alloc]init];s.name = @"bill";s.delegate = m;[s rentHouse];?----------------------------------------------------------------------------------------------------------------------------
SaleHuse.h
#import <Foundation/Foundation.h>@protocol SaleHouse <NSObject>//@required -(void)saleHouse; -(void)payMoney; @endHouseSaler.h
#import <Foundation/Foundation.h>#import "SaleHouse.h"@class Landlord;@interface HouseSaler : NSObject <SaleHouse> {Landlord *_customer; }@property(assign,nonatomic)Landlord *customer;-(void)registerInfo:(Landlord *)aCustomer; @endHouseSaler.m
#import "HouseSaler.h" #import "Landlord.h" @implementation HouseSaler@synthesize customer = _customer; -(void)saleHouse {NSLog(@"我是中介,我替登記者賣房");[self payMoney]; }-(void)payMoney {NSLog(@"我是中介,我賣了房了");[self.customer receiveMoney]; }-(void)registerInfo:(Landlord *)aCustomer {self.customer = aCustomer;self.customer.delegate = self;//注冊 } @end
Landlord.h
#import <Foundation/Foundation.h> #import "HouseSaler.h" @interface Landlord : NSObject {id<SaleHouse> _delegate;//代理(實現協議的對象) }@property(nonatomic,assign)id<SaleHouse> delegate;-(void)saleHouse; -(void)receiveMoney;@endLandlord.m
#import "Landlord.h"@implementation Landlord @synthesize delegate = _delegate;-(void)saleHouse {NSLog(@"我是房東,我已經將房子登記到中介了");if ([self.delegate conformsToProtocol:@protocol(SaleHouse)])//注意:要中介中心登記注冊后才有代理{[self.delegate saleHouse];}}-(void)receiveMoney {NSLog(@"我是房東,錢我收下了,謝謝中介了"); } @endAppDelegate.m
Landlord *landlord = [[Landlord alloc]init];HouseSaler *houseSaler = [[HouseSaler alloc]init];[houseSaler registerInfo:landlord];//房東到中介注冊成客戶[landlord saleHouse];?----------------------------------------------------------------------------------------------------------------------------
協議繼承協議:
1.創建一個定義協議1的BaseClass類,并回調協議中的方法.
BaseClass.h
#import <Foundation/Foundation.h> @protocol BaseClassDelegate;@interface BaseClass : NSObject@property(nonatomic,assign)id <BaseClassDelegate>delegate; -(void)oldmethod;@end@protocol BaseClassDelegate <NSObject>-(void)oldmessage:(NSString *)str;@endBaseClass.m
#import "BaseClass.h"@implementation BaseClass @synthesize delegate;-(void)oldmethod {[delegate oldmessage:@"BaseClass oldmethod called"]; } @end2.創建一個BaseClass的子類SubClass,且定義協議2,并回調協議1和協議2中的代理方法
SubClass.h
#import <Foundation/Foundation.h> #import "BaseClass.h"@protocol SubClassDelegate;@interface SubClass : BaseClass @property(nonatomic,assign)id <SubClassDelegate>subdelegate; -(void)newmethod; @end@protocol SubClassDelegate <NSObject,BaseClassDelegate> @optional -(void)newmessage:(NSString *)str;@endSubClass.m
#import "SubClass.h"@implementation SubClass @synthesize subdelegate; -(void)oldmethod {[super.delegate oldmessage:@"SubClass oldmethod called"]; }-(void)newmethod {[super.delegate oldmessage:@"SubClass newmethod called"];[self.subdelegate newmessage:@"SubClass newmethod called"]; }@endAppDelegate.m
BaseClass *b = [[BaseClass alloc]init];b.delegate = self;[b oldmethod];SubClass *s = [[SubClass alloc]init];s.delegate = self;//因為對象是動態的所以不能繼承下來s.subdelegate = self;[s oldmethod];[s newmethod]; -(void)oldmessage:(NSString *)str {NSLog(@"oldmessage:%@",str); }-(void)newmessage:(NSString *)str {NSLog(@"newmessage:%@",str); }?
轉載于:https://www.cnblogs.com/huen/p/3533097.html
總結
- 上一篇: Android-----Resource
- 下一篇: TOJ 2815 Connect the