2012-02-02 49 views
9

Tôi biết rằng bạn có thể khai báo một hàm C bên ngoài một lớp, nhưng có thể khai báo một phương thức Objective-C bên ngoài một lớp không?Có thể khai báo một phương thức Objective-C bên ngoài một lớp không?

Ví dụ:

// Works 
void printHelloC() 
{ 
    NSLog(@"Hello."); 
} 

// Error 
-(void) printHelloOC 
{ 
    NSLog(@"Hello."); 
} 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     printHelloC(); 
     [self printHelloOC];// 'self' obviously would not work but you get the idea 
    } 
    return 0; 
} 

Trả lời

4

Tùy theo. Bạn có thể làm điều gì đó tương tự với phương pháp thêm vào lúc chạy:

#import <objc/runtime.h> 

void myCustomMethod(id self, SEL _cmd, id arg1, id arg2) 
{ 
    NSLog(@"This is a test, arg1: %@, arg2: %@", arg1, arg2); 
} 

int main(int argc, char *argv[]) 
{ 
    Class NSObjClass = [NSObject class]; 

    class_addMethod(NSObjClass, @selector(myNewMethod::), (IMP) myCustomMethod, "[email protected]:@@"); 

    NSObject myObject = [NSObject new]; 

    [myObject myNewMethod:@"Hi" :@"There"]; 

    [myObject release]; 

    return 0; 
} 

Nhưng đó là về nó bên ngoài cấu trúc @class và nó thực sự chỉ che đậy những gì xảy ra với một danh mục.

+0

Câu trả lời hay, nhưng tên phương thức của bạn là một chút nhầm lẫn, vì nó thực sự là một phương thức không phải là một lựa chọn – dreamlax

+0

@dreamlax điểm tốt, cố định –

0

Một phương pháp mà không có một lớp liên kết là một khái niệm vô nghĩa. Chức năng, như bạn đã lưu ý, chỉ là tốt.

+5

Không nhất thiết phải đúng. Bạn có thể có một bộ chọn thực hiện mã cụ thể độc lập với đối tượng là gì, miễn là nó thực hiện một tác vụ nào đó. Đó là lý do đằng sau các giao thức. –

+0

@ RichardJ.RossIII - để làm những gì bạn mô tả chắc chắn bạn xác định một * loại * trên 'NSObject'? – CRD

+0

@CRD không nhất thiết, bạn có thể làm điều tương tự với phương pháp bổ sung (xem câu trả lời của tôi). Mà về cơ bản là một cách phức tạp hơn để làm những gì một thể loại nào. –

4

Bạn có thể sử dụng danh mục cho việc này.

Là một phương pháp dụ:

@interface NSObject (MONStuff) 
- (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
- (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

NSObject * obj = ...; 
[obj printHelloOC]; 

Là một phương pháp Class:

@interface NSObject (MONStuff) 
+ (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
+ (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

[NSObject printHelloOC]; 

Tất nhiên, bạn phải kết hợp điều đó với một lớp học - vì vậy nó không chính xác sự giống như bạn đã đăng, nhưng đó là một tuyên bố + định nghĩa gần riêng biệt với tuyên bố lớp học chính thức.

+0

Danh mục chỉ đơn giản là mở rộng một lớp - theo định nghĩa bất kỳ phương pháp nào được khai báo trong danh mục nằm trong một lớp ... –

+0

@Carl Tôi mở rộng trên đó – justin

+0

Phương thức mới của bạn là phương thức 'NSString'. Đó không phải là bên ngoài một lớp - đó là * bên trong * 'NSString'! –

0

Chức năng mục tiêu c luôn được liên kết với một lớp. Nếu bạn có nghĩa là bạn muốn sử dụng một hàm mục tiêu-c mà không instantiating một lớp, bạn có thể tất nhiên viết một phương thức lớp (chú ý dấu cộng thay vì gạch nối thông thường)

@interface Test 

+ (void)aClassMethod; 

@end 

sau đó bạn có thể gọi nó bằng cách gọi

[Test aClassMethod]; 
+2

Không phải lúc nào cũng đúng. Ví dụ, nếu bạn sử dụng phương thức swizzling, bạn có thể thêm một hàm vào nhiều lớp với nhiều bộ chọn! –

+0

Có lẽ ...nhưng phương pháp nổi loạn là một khái niệm khá tiên tiến, và chắc chắn không phải cái gì mà bạn không nên cân nhắc cẩn thận. – futureelite7

+0

Nó không phải là phức tạp, bạn chỉ cần bao gồm thời gian chạy, tạo ra chức năng của bạn, và thêm phương pháp vào lớp với một bộ chọn. Nó không có một nhà khoa học tên lửa để làm, và trao đổi phương pháp triển khai thực hiện chỉ là dễ dàng. –

0

Không, điều đó là không thể - bạn sẽ cần phải sử dụng các hàm C toàn cục hoặc các phương thức lớp (+).

+1

Có thể, thời gian chạy Objective-C cho phép bạn thêm các phương thức vào một lớp trong khi chương trình đang thực thi. Nó thậm chí còn cho phép bạn tạo ra các lớp hoàn toàn mới. Bạn có thể định nghĩa cách thực hiện phương thức Objective-C và sau đó kết hợp phương thức đó với một lớp và một bộ chọn. – dreamlax

+0

Vâng, thực sự có thể tạo các lớp động. Nó không phải là câu hỏi, tuy nhiên. Câu hỏi đặt ra là liệu có thể xác định và thực hiện các phương thức Objective-C a-la các hàm C toàn cầu (hoặc, nói, các bao đóng JavaScript toàn cầu). Điều đó là không thể. Các phương thức Objective-C phải được định nghĩa như là một phần của một lớp (class hoặc instance scoped). –

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