簡體   English   中英

Obj-C中[object variable]和object.variable之間的區別?

[英]Difference between [object variable] and object.variable in Obj-C?

我今天正在制作一個程序並且遇到了這個奇怪的bug。 我有一個分配了動作的UIButton。 這個動作是這樣的:

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

令我困惑的是,當我第一次寫它時, if行是

if (e.tag==SOMETAG)

XCode拒絕編譯它,說

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

但我認為這兩個是相同的。

那么它們在什么情況下不一樣呢?

僅當變量具有聲明的關聯屬性,或者存在可用的符合鍵值編碼的訪問器方法時,才可以使用點表示法。 屬性語法允許您為符合鍵值編碼的變量“合成”訪問器方法,實際上,這就是點符號的工作方式。

聲明屬性時, someObject.variable等同於[someObject variable]

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

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

((MyObject*)e).tag

似乎有一些關於屬性和點符號的誤解。 點表示法可以與任何訪問器方法一起使用,無論是否聲明為屬性,只要編譯器知道點左側的對象具有訪問器。 您不需要使用@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;
}

關鍵點是編譯器必須知道對象是否存在訪問器,這意味着必須正確地鍵入對象(即不能是id)。

您可以使用提供的obj.prop getter語法(handwavily)編譯器具有方法調用[obj prop]的原型,並提供setter語法[obj setProp:blah]。 這意味着您可以將它用於NSNumberFormatter這樣的類,它們不聲明屬性。 這是否可取是值得商榷的問題。

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

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

您不能在id對象上使用點表示法。 這只是他們的規則。

這是傑克在我評論之前刪除了他的答案:-)

您不是直接訪問實例變量,點符號僅用於通過@synthesized的getter和setter方法獲取屬性。 您正在向對象發送消息,在這種情況下會導致調用這些getter / setter方法。 您不能使用點表示法直接訪問成員變量,也不能直接調用方法 - 必須將其設置為屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM