2016-02-18 14 views
5

Ví dụ, cho phép xem xét đoạn mã sau dưới ARC:phương pháp Swizzling, mà mặc nhiên trả về một đối tượng giữ lại dưới ARC

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 

@implementation NSDate (MyEvilHack) 

+ (void)load { 
    Method originalMethod = class_getInstanceMethod(self, @selector(copyWithZone:)); 
    Method newMethod = class_getInstanceMethod(self, @selector(myCopyWithZone:)); 
    method_exchangeImplementations(originalMethod, newMethod); 
} 

- (id)myCopyWithZone:(NSZone *)zone { 
    id result = [self myCopyWithZone:zone]; 
    // do customization 
    return result; 
} 

@end 

Trong mã này, phương pháp ban đầu copyWithZone: là ngầm trả về một đối tượng giữ lại, vì nó thuộc về copy gia đình phương pháp. Nhưng myCopyWithZone: của tôi thì không.

Tôi mong đợi sự cố, nhưng có vẻ như mã này hoạt động bình thường. Tất nhiên, tôi có thể đổi tên phương pháp của mình để tránh nhầm lẫn. Nhưng tôi tò mò chính xác những gì xảy ra dưới mui xe?

Trả lời

4

Như bạn biết, ARC kiểm tra tên phương thức, áp dụng quy ước đặt tên quản lý bộ nhớ Cocoa và xác định cách thức hoạt động của phương thức. Đối với một phương thức mà nó biên dịch, nó làm cho phương thức tuân theo các quy ước đó. Đối với một phương thức mà nó đang gọi, nó giả định phương thức tuân theo các quy ước đó.

(Người ta có thể ghi đè lên các công ước sử dụng chức năng thuộc tính, nhưng bỏ qua cho bây giờ.)

Khi ARC được biên soạn -myCopyWithZone: của bạn, nó xác định rằng một phương pháp như vậy phải trả lại một tham chiếu +0. Khi nó gặp cuộc gọi đến (rõ ràng) -myCopyWithZone:, nó giả định rằng phương thức trả về một tham chiếu +0. Kể từ những trận đấu đó, nó không nên giữ lại hoặc giải phóng bất cứ điều gì. (Vâng, nó có thể tạm thời giữ lại kết quả, nhưng nó phải cân bằng với một autorelease.) Kết quả là, thực tế +1 tham chiếu trả lại bởi -copyWithZone: ban đầu tồn tại cho người gọi và người gọi đã mong đợi một tham chiếu +1, vì vậy đó là tất cả tốt.

Có thể bạn có thể khiến ARC tăng tốc bằng cách gọi một phương thức khác (phương thức này sẽ không được đổi tên hiệu quả bằng cách chuyển đổi) trả về tham chiếu +1. Nếu nó được trả lại và vì phương thức hiện tại được mong đợi trả về một tham chiếu +0, nó sẽ tự động trả về nó. Người gọi sẽ không giữ lại nó vì nó đang mong đợi một tham chiếu +1. Vì vậy, các đối tượng sẽ được sớm deallocated, có khả năng dẫn đến một vụ tai nạn.

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