2010-06-10 75 views
3

我今天正在開發一個程序,並且遇到了這個奇怪的bug。我有一個分配了操作的UIButton。該行動是這樣的:Obj-C中[object variable]和object.variable之間的區別?

-(void) someaction:(id) e 
{ 
    if ([e tag]==SOMETAG) 
    { 
     //dostuff 
    } 
} 

什麼讓我困惑的是,當我第一次寫吧,如果線是

if (e.tag==SOMETAG) 

的XCode拒絕編譯它,說

error: request for member 'tag' in 'e', which is of non-class type 'objc_object*' 

但我認爲這兩者是相同的。

那麼在什麼情況下他們不一樣?

+0

我是一個objective-c noob ...很好的問題。 – codemonkey 2010-06-10 23:46:05

回答

5

僅當變量具有聲明的關聯屬性,或者存在可用的鍵值編碼兼容訪問器方法時,纔可以使用點表示法。屬性語法允許你爲符合Key-Value-Coding的變量「綜合」訪問器方法,而且這實際上就是點符號的工作方式。

當宣佈財產時,someObject.variable相當於[someObject variable]

當一個對象被鍵入爲id時,編譯器不知道該對象具有的任何屬性。 id是指向任何對象的指針,實際上是一個void *。

您可以將您的對象轉換爲您所期望的類型,這樣您可以使用屬性語法。

((MyObject*)e).tag 
+0

不知道。這很有道理。感謝您的幫助。 – jergason 2010-06-11 00:23:04

+2

這是錯誤的。您可以將點符號與任何*聲明的* accessor方法一起使用,無論聲明爲屬性還是方法/方法對。 – JeremyP 2010-06-11 09:46:58

+0

是的,你是對的。我會更新我的答案。 – Jasarien 2010-06-11 11:04:30

0

對id對象不能使用點符號。這只是他們的一個規則。

0

這是傑克誰刪除了他的答案之前,我可以:-)

評論你不是直接訪問實例變量,點號只用於在性能獲得,通過吸氣和你合成的setter方法。您正在向對象發送消息,在這種情況下會導致getter/setter方法被調用。您不能使用點符號直接訪問成員變量,或者直接調用方法 - 必須將其設置爲屬性。

1

您可以使用obj.prop getter語法(handwavily)提供編譯器具有方法調用[obj prop]的原型,並提供setter語法[obj setProp:blah]。這意味着你可以將它與NSNumberFormatter這類不聲明屬性的類一起使用。這是否可取是有爭議的。

如果您不介意所有括號,您可以使用((Foo *)obj).prop將其轉換爲正確的對象類型。

請注意,未知方法的返回類型默認爲id(因此您可能會比較id與int),並且您的發件人可能不是UIView(它可能是UIBarButtonItem)。如果您認爲e符合< NSObject>,那麼執行if ([(id<NSObject>)e isKindOfClass:[UIView class]] && [(UIView*)e tag] == sometag)會更安全一些。

2

這裏似乎有一些關於屬性和點符號的誤解。點符號可以與任何訪問器方法一起使用,不管是否聲明爲屬性,只要編譯器知道點左側的對象具有訪問者。您不需要使用@property語法。您不需要綜合訪問器。以下是完全有效的Objective-C,其將乾淨編譯:

#import <Cocoa/Cocoa.h> 
@interface AClass 
{ 
} 

-(NSString*) aProperty; 

@end 

@implementation AClass 

-(NSString*) aProperty 
{ 
    return @"some text"; 
} 

@end 

int main() 
{ 
    AClass* foo = [[ACLass alloc] init]; 
    NSLog(@"%@", foo.aProperty); 
    return 0; 
} 

的關鍵點是,編譯器必須知道如果存取器存在這意味着該對象必須鍵入正確的對象(即,可以」 t是id)。

+0

爲什麼不將點符號限制爲@屬性聲明的訪問器?它似乎可以解決模棱兩可的情況(例如'.uppercaseString'),並允許類作者使編譯器強制執行它們的意圖。是否有技術或哲學原因? – 2010-07-04 22:16:56

+0

@Preston:我不確定你對含糊情況的看法。對於'uppercaseString' *應該做什麼來看,我似乎沒有任何含糊之處。 – JeremyP 2010-07-05 07:31:15

+0

能夠使用點符號調用'-uppercaseString'意味着它是一個屬性。 – 2010-07-06 19:42:13

相關問題