2012-01-21 21 views
16

Với này:Làm thế nào để nhanh chóng một lớp trong Objective-C mà không kế thừa từ NSObject

Person.h:

@interface Person 
{ 
} 
- (void) sayHello; 
@end 

Person.m:

#import "Person.h" 

@implementation Person 

- (void)sayHello 
{ 
    printf("%s", "Steve"); 
} 

@end 

thế nào bạn khởi tạo Người? Tôi cố gắng này:

Person *p = [Person new]; 

Điều đó không làm việc, cũng không phải này:

Person *p = [Person alloc]; 

[UPDATE]

Tôi quên nói, tôi đã cố gắng kế thừa từ NSObject, mới và alloc công trinh. Tôi chỉ tò mò nếu chúng ta có thể khởi tạo một lớp không kế thừa từ NSObject?

+8

Có gì sai với 'Người' kế thừa từ 'NSObject'? – Costique

+0

+1 vì đây là một câu hỏi rất thú vị, mặc dù giá trị thực tế có thể rất ít. – vikingosegundo

+0

@Costique: Không có gì, chỉ có rất nhiều hướng dẫn tôi tìm thấy trên web đã không đề cập đến rằng đó là một yêu cầu (nghĩa là kế thừa từ NSObject). Ví dụ: http://en.wikibooks.org/wiki/Objective-C_Programming/syntax Đã thử kế thừa từ Object, nhưng '[Person new]' không hoạt động quá – Hao

Trả lời

28

Bạn hoàn toàn có thể làm như vậy. Lớp học của bạn chỉ cần thực hiện +alloc chính nó, cách mà NSObject thực hiện. Tại cơ sở, điều này chỉ có nghĩa là sử dụng malloc() để lấy một đoạn bộ nhớ đủ lớn để phù hợp với cấu trúc xác định một thể hiện của lớp học của bạn.

Quản lý bộ nhớ được tính tham chiếu cũng sẽ đẹp (retain/release); đây thực sự là một phần của NSObjectprotocol. Bạn có thể áp dụng giao thức và thực hiện các phương thức này.

Để tham khảo, bạn có thể nhìn vào the Object class, mà là một gốc ObjC lớp như NSObject, mà Apple cung cấp tại kho lưu trữ mã nguồn mở của mình cho thời gian chạy Objective-C:

@implementation Object 

// Snip... 

+ alloc 
{ 
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
} 

// ... 

- init 
{ 
    return self; 
} 

// And so on... 

đó đang được nói, bạn nên nghĩ về NSObject là một phần không thể thiếu trong thời gian chạy ObjC. Có rất ít lý do để thực hiện lớp gốc của riêng bạn bên ngoài sự tò mò, điều tra hoặc thử nghiệm (tuy nhiên, không nên nản lòng).

+5

+1 đây hoàn toàn là câu trả lời đúng. Thực sự, thời gian * duy nhất * khi bạn không muốn kế thừa từ 'NSObject' là khi bạn định làm gì đó * về cơ bản khác nhau * về quản lý bộ nhớ. –

+0

Câu trả lời sâu sắc về mục tiêu-c vượt xa: "Nhấp vào nút sáng bóng đó trong XCode" ... Tuyệt vời! +1 –

+0

Câu trả lời này cũng có áp dụng cho nhanh không? – user3797599

-6

bạn không thể ..

Alloc và ..copy mới init tất cả các phương pháp này được định nghĩa trong NSObject ..

Bạn cũng không thể tạo riêng của bạn từ táo không cung cấp lớp triển khai NSObject..so bạn phải kế thừa từ NSObject hoặc lớp con của nó để bạn có thể khởi tạo lớp học của mình

+2

tất nhiên là có thể. Apple cũng đã làm điều đó. bạn "chỉ" phải làm quản lý bộ nhớ kiểu C của riêng bạn. NSObject không phải là một phần của ngôn ngữ Objective-C, vì không phải là Foundation, UIKit, AppKit,… – vikingosegundo

+1

Tôi không hiểu tại sao bạn chưa xóa câu trả lời này khi nó quá rõ ràng. Kiếm cho mình một huy hiệu Áp lực ngang hàng! :) –

4

Bạn phải:

  1. Kế thừa từ NSObject,
  2. Do lớp một "nghèo của con người" với mallocs của riêng bạn, vv, hoặc
  3. Sử dụng Objective-C++ và tạo ra một ++ lớp C.

Tất nhiên, cả hai loại kia không phù hợp với quản lý lưu trữ mục tiêu-C và giao thức cuộc gọi của họ, v.v. khác nhau.

+2

Hầu như! Đối với 2, bạn có thể chỉ cần thực hiện + phân bổ, -retain, -release, vv ... về malloc và refcount của riêng bạn. Bằng cách thực hiện giao thức NSObject *, bạn có thể tham gia khá nhiều công cụ một cách minh bạch. –

+0

-1 bạn không * có * để kế thừa từ 'NSObject'. Có nhiều lớp không có, chẳng hạn như 'NSProxy'. –

+1

@DaveDeLong có nghĩa là bạn phải * hoặc * làm 1. * hoặc * 2. * hoặc * 3. –

3

Có (rất có thể) không có lý do chính đáng để không muốn kế thừa từ NSObject, nhưng có nhiều lý do chính đáng để làm như vậy.

Tôi sẽ tò mò về lý do tại sao bạn không muốn kế thừa từ NSObject. Tôi đoán nó bắt nguồn từ sự thiếu hiểu biết hơn là một nhu cầu thực sự.

Nhưng ngay cả khi không biết lý do đó: Đừng làm điều đó. Thật khó để làm tốt điều này theo cách mà nó vẫn chơi tốt với các lớp Objective-C khác hầu như không thể.

Dù sao, bạn đang khởi tạo các đối tượng theo cách ẩn nội dung thực sự.Trong thời gian ở Java, bạn thường tạo ra các trường hợp thông qua phương thức constructor mặc định new, trong Objective-C bạn nhanh chóng bằng cách gọi alloc trên lớp và sau đó init trên dụ:

Person *aPerson = [[Person alloc] init]; 

(Đó là thể để chỉ cần sử dụng Person new, nhưng tôi sẽ không làm điều đó bởi vì nó ẩn những gì thực sự được thực hiện từ bạn)

Bạn thực hiện lớp học của bạn sao cho bạn kế thừa từ NSObject và sau đó, nếu cần, hãy viết phương pháp init của riêng bạn.

Nếu bạn muốn đăng nhập vào giao diện điều khiển, sử dụng NSLog:

NSLog(@"Hello %@", @"Steven"); 

(@"" là một nhà xây dựng đặc biệt cho một NSString Strings trong Objective-C không phải là mảng byte, nhưng các đối tượng..)

+3

Tất nhiên, trong Objective-C 'new' chỉ là viết tắt của vani' alloc/init'. –

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