2013-04-10 72 views
-2
#import <UIKit/UIKit.h> 
#import <MapKit/MapKit.h> 
#import <CoreLocation/CoreLocation.h> 

@interface CustomAnnotation : NSObject <MKAnnotation> 
{ 
    CLLocationCoordinate2D coordinate; 
    NSString *title; 
    NSString *subTitle; 
} 

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; 
@property (nonatomic, copy) NSString *title; 
@property (nonatomic, copy) NSString *subtitle; 

- (id)initWithLocation:(CLLocationCoordinate2D)coords title:(NSString *)aTitle andSubtitle:(NSString*)aSubtitle; 

@end 

我正在做一個具有上述代碼的教程。iOS /目標C:代碼說明

我的問題:

  1. 是什麼在支撐與@property定義一個變量之間的區別?
  2. 爲什麼我們需要在兩個地方定義變量?
  3. 在.h和.m文件中聲明#import有什麼區別?

請回答所有三個問題。

+0

1st ...爲了訪問其他類中的變量,我們使用@property ...如果你沒有,那麼你不能在其他類中使用....第二,如果你聲明與'財產'你不需要再次聲明他們...... 3rd--無法讓你 – 2013-04-10 15:15:44

回答

2

聲明括號之間的變量具有實際創建該變量的存儲的效果。

@property聲明將訪問器方法並自動生成支持ivar爲您,這使得第一個聲明是多餘的。因此,您可以從大括號中刪除聲明,並保留屬性聲明。

自動合成的伊娃將有一個領先的下劃線,這使得它更清晰,當你直接訪問伊娃或通過訪問者例如,

@property (nonatomic, strong) MyThing *myThing; 

將在你的類可直接與

_myThing = [[MyThing alloc] init]; 

或通過存取

[self setMyThing:[[MyThing alloc] init]]; 

一般來說大部分時間通過訪問器會是你想要的,除非你是內部重寫訪問器方法。


曾經有一段時間,當@property@synthesize只會爲你生成存取方法,你不得不採取確保存儲空間供使用創建的護理 - 聲明一個大括號之間的伊娃。

然後,東西移動,@property@synthesize都是你所需要的,並且後援伊娃會自動合成。

目前的狀態是@property是所有必需的(在大多數情況下)和@synthesize隱式完成。


進口

沒有技術差異的聲明真的只是抓住你要導入的文件的內容並轉儲他們在它的位置。

你必須要小心循環依賴的

FileA   | FileB 
----------------+---------------- 
#import "FileB" | #import "FileA" 
       | 

這將成爲名副其實的

FileA   |<- 
----------------| \ 
#import "FileB" |/
#import "FileA" |-' 

FileB   |<- 
----------------| \ 
#import "FileA" |/
#import "FileB" |-' 

兩個文件將在一個圓形環路試圖進口他們自己這僅僅是行不通的。

所以避免這個問題的最簡單的方法是在頭文件中進行最小量的導入。

如果你需要在你的頭,以引用類,然後使用前向聲明(@class

所以,你最終這個

@class MyClass 

@interface MyOtherClass : NSObject 

@property (nonatomic, strong) MyClass *mything; 

@end 

你基本上已經告訴MyClass存在編譯器等你可以參考它。

然後您可以在實施文件中導入MyClass的實際標題。

#import "MyOtherClass.h" 
#import "MyClass.h" 

@implementation MyOtherClass 

@end 
+0

這是正確的......就像一個補充,如果你讓編譯器自動合成,你的後備iVars將被創建(無形地)與領先的下劃線。例如,如果您有財產 @property BOOL myProperty 而且您沒有在.m文件中手動合成它,您可以使用_myProperty直接訪問後備iVar。 無論如何,大多數時候您想要使用生成的訪問器(例如,self.myProperty = YES),但知道這一點仍然很重要。 – 2013-04-10 15:27:50

3

1.在花括號中定義變量與 @property之間有什麼區別?

 
    @interface XXX:YYY 
    { 
     place for ivars 
    } 
    place for properties. ivars prefixed with _(underscore) gets created automatically in new compiler. 
    @end 

2.爲什麼我們需要在這兩個地方定義變量?

這是舊的風格,現在它只是完成。只有@property就足夠了。

3.在.h和.m文件中聲明#import有什麼區別?

如果您希望某些類的對象作爲屬性在.h中定義它,並且只需要在實現中進行導入,則只需在.m中導入。

如果你把在頭文件中所有的#imports,則沒有兩類 可以互相依賴對方,因爲文件無法導入文件 是進口的。如果您將#import放入實施文件中,則另一方面, 問題消失。

從夾頭的提取物,Best practice and rationale: #import in .m or .h

1

1)有什麼定義在大括號的變量與 @property之間的區別?

因爲@property定義變量的態度,以及它的輔助功能限制,如果你不寫@property它也將工作,但如果你想編譯器自動創建變量的getter和setter方法,然後在使用@property@synthesize它。 m文件。

2)爲什麼我們需要在兩個地方定義變量?

第一個答案的下半部分包括答案。簡短的「定義的setter & getter方法以及它的輔助功能」

3)是什麼在.H宣佈#import VS .m文件之間的區別?

如果導入.h文件中使用它,它會提供給該類的所有子類,而如果你的.m文件導入這將是可用的(範圍)僅.m文件

1
  1. 在大括號中,您可以聲明任何您希望的實例變量。大括號之外是聲明@properties的位置,它自動爲對象生成一個getter和setter,以及您在實現文件中定義的任何非私有方法。

  2. 由於@Anoop Vidya提到,在兩個地方聲明變量現在是多餘的,沒有必要。

  3. 導入文件的一般經驗法則:導入彼此的文件會創建運行時錯誤。因此,遵守以下規則:

如果您需要另一個類的實例變量,用@class導入你的頭的其他類,然後#import它在實現文件。

如果你不需要從你創建的另一個類創建一個ivar,那麼只需將它#import它放到你的實現文件中。

如果按照以下步驟仍然遇到相互依賴性問題,那麼您可能需要重新考慮設計。