2009-08-28 26 views
41

Tôi có một câu hỏi rất cơ bản. Tôi là một lập trình viên iPhone mới. Câu hỏi của tôi là ai có thể cho tôi biết làm thế nào tôi có thể vượt qua các giá trị bằng cách tham chiếu đến một hàm trong obj. C? Tôi biết làm thế nào để làm điều đó trong VB và C#. Nhưng không biết làm thế nào để làm điều đó trong Obj c.Cách chuyển giá trị theo tham chiếu trong mục tiêu C (iphone)

Cảm ơn

Trả lời

13

Không có đi qua bằng cách tham khảo (trong C++ cho tinh thần) trong C. Mục tiêu Bạn có thể vượt qua đối tượng của bạn bằng con trỏ, và với nhiều loại nguyên thủy theo giá trị.

Ví dụ:

void func(NSString* string) 
{ 
    ... 
} 

void func(NSInteger myint) 
{ 
... 
} 

.. 
NSString* str = @"whatever"; 
NSInteger num = 5; 

func(str); 
func(num); 
+1

Tôi hoàn toàn đồng ý! Luôn theo nghĩa C++: Việc truyền tham số có nghĩa là nếu bạn thay đổi tham số của phương thức (hàm) để trỏ đến obj khác thì thế giới bên ngoài sẽ bị ảnh hưởng (param chỉ là một tên khác của var được truyền vào), và điều này không thể thực hiện được trong Objective C mà không có dereferencing tham số, bởi vì luôn luôn một ** copy ** của con trỏ được chuyển tới các phương thức (functions). – Vassilis

+1

Trong mục tiêu C, con trỏ dereferencing của một đối tượng là cực kỳ hiếm. Nếu bạn muốn thay đổi giá trị của tham số phương thức, thông thường bạn sử dụng một trong hai cách sau. Frist, sử dụng con trỏ trỏ tới con trỏ (double indirection, ký hiệu là **), giống như trong nhiều ví dụ của NSError. Thứ hai, phương thức bọc như một khối. Sau đó đặt biến trong phạm vi từ vựng giống như khối, và biểu thị nó bằng kiểu lưu trữ '__block'. – Philip007

0

Nó phụ thuộc vào những gì bạn có ý nghĩa. Điều gần nhất C (và do đó Objective-C) có một kiểu tham chiếu là con trỏ. Như tên của nó, con trỏ trỏ đến dữ liệu tồn tại ở một nơi khác. Để có được điều được chỉ ra, bạn phải dereference con trỏ. Các đối tượng trong Objective-C không bao giờ được truy cập trực tiếp - bạn luôn sử dụng con trỏ để nói chuyện với chúng. Bạn cũng có thể truyền con trỏ tới các loại khác ngoài các đối tượng.

Con trỏ là một chủ đề khó khăn. Tôi chắc chắn sẽ khuyên bạn nên đọc lên trên C để có được một cảm giác cho họ.

88

Pass-by-tham chiếu trong Objective-C là như nhau vì nó là trong C.

Tương đương với C# mã sau:

void nullThisObject(ref MyClass foo) 
{ 
    foo = null; 
} 

MyClass bar = new MyClass(); 
this.nullThisObject(ref bar); 
assert(bar == null); 

- (void)nilThisObject:(MyClass**)foo 
{ 
    [*foo release]; 
    *foo = nil; 
} 

MyClass* bar = [[MyClass alloc] init]; 
[self nilThisObject:&bar]; 
NSAssert(bar == nil); 

- (void)zeroThisNumber:(int*)num 
{ 
    *num = 0; 
} 

int myNum; 
[self zeroThisNumber:&myNum]; 
NSAssert(myNum == 0); 
+7

Hãy sửa tôi nếu tôi sai!Nhưng tôi nghĩ rằng trong ví dụ 'zeroThisNumber' ở trên, con trỏ được truyền bởi ** value **, có nghĩa là một bản sao của con trỏ được truyền, đó là nếu chúng ta thay đổi' num' để trỏ đến một 'myNum' khác sẽ không thay đổi. Chúng tôi theo quy ước nói "bằng cách tham khảo" là có địa chỉ của obj gốc, chúng tôi có thể trực tiếp thay đổi nó (bằng cách dereferencing nó). – Vassilis

+0

Tôi thực sự không biết cách chuyển giá trị bằng tham chiếu thực trong mục tiêu C như trong C++. Tôi luôn luôn sử dụng '*' và '**' như được mô tả bởi Darren, nhưng vẫn còn một bản sao của con trỏ được truyền như tôi đã đề cập trong bình luận trước của tôi (công việc được thực hiện mặc dù). Tất nhiên đây là một loại vấn đề lý thuyết. – Vassilis

+2

Trong ví dụ zeroThisNumber, num được truyền theo tham chiếu (mặc dù về mặt kỹ thuật, đây không phải là nghĩa của tham chiếu C++). Trong ví dụ này, địa chỉ của giá trị num được chuyển tới zeroThisNumber. Điều này cho phép giá trị được thay đổi trong phương thức và có thay đổi được phản ánh trong người gọi. Những gì bạn đang đề cập đến sẽ là một tham chiếu đến một tài liệu tham khảo ... vì nó là ... đôi hướng. Nếu num không được chuyển qua tham chiếu, giá trị của num sẽ được sao chép và được đặt trên stack. Mọi thay đổi về num trong zeroThisNumber sẽ được thực hiện trên stack và bị mất khi phương thức trả về. – Jason

13

Nếu bạn sử dụng Objecti đã C++, mà bạn có thể thực hiện bằng cách đặt tên tập tin của bạn với .mm gia hạn, hoặc nói với Xcode để biên dịch tất cả các nguồn như Objective C++, sau đó bạn có thể vượt qua tài liệu tham khảo trong giống như cách bạn làm với C++, ví dụ:

- (OSStatus) fileFileInfo: (FileInfo&)fi; 
0

Có một đối số để có nếu bạn muốn nhận được nhiều hơn một địa chỉ từ một cuộc gọi hàm kết quả. Thay vào đó, bạn có thể làm như vậy bằng cách tạo một lớp trình bao bọc và chuyển qua lớp đó. Ví dụ:

@interface AddressWrapper : NSObject { 
    NSArray  *array; 
    NSString *string; 
} 

@property (nonatomic, assign) NSArray *array; 
@property (nonatomic, assign) NSString *string; 
@end 

Trong * .m:

@implementation AddressWrapper 
@synthesize array, string; 
@end 



-(void) getAddresses: (AddressWrapper*) wrapper { 
    wrapper.array = myNSArray; 
    wrapper.string = myNSString; 
} 
7

Hãy thử cách này:

-(void)secondFunc:(NSInteger*)i 
    { 
     *j=20; 
    //From here u can change i value as well 
    //now i and j value is same (i.e i=j=20) 
    } 
    -(void) firstFunc 
    { 
     NSInteger i=5; 
     [self secondFunc :&i]; 
    //i value is 20 
    } 

Hy vọng nó giúp !!

Các vấn đề liên quan