Why ARC forbids calls to undeclared methods?

2020-03-24 02:49发布

When using manual memory management we can write a call to a method which is not declared in the class. What we get during compilation in this case is warning only. This is what Wikipedia states on one of the most distinctive Objective-C features:

The Objective-C model of object-oriented programming is based on message passing to object instances. In Objective-C one does not simply call a method; one sends a message. This is unlike the Simula-style programming model used by C++. The difference between these two concepts is in how the code referenced by the method or message name is executed. In a Simula-style language, the method name is in most cases bound to a section of code in the target class by the compiler. In Smalltalk and Objective-C, the target of a message is resolved at runtime, with the receiving object itself interpreting the message

So why it is compilation error in ARC? What are the reasons to break such a powerful feature of the language? What's so important about that i'm not aware of? Can anybody explain this? Thanks

2条回答
倾城 Initia
2楼-- · 2020-03-24 03:03

ARC manages retain/release calls. To do so properly it needs to know how all methods you use behave.

It needs the message signatures you use. it gets them from header files. Therefore it enforces you to have headers/declarations for all methods you use.

It DOES work without headers: you can trick it by using NSSelectorFromString but that isn't really safe and arc wants to be sure about everything by default.

查看更多
够拽才男人
3楼-- · 2020-03-24 03:21

There is some information about it in this discussion:

Under ARC, the compiler needs to now exactly the kind of ownership the method returns. The default in this case is that the object is not owned by the caller, but in the actual declaration the object may be owned by the caller ("ns_returns_retained" attribute), conversely, you may have a owning method like newBar that returns a non-retained object ("ns_returns_not_retained" attribute), in the former case you get an under-release in the latter you get an over-release, which is detrimental to ARC.

To make ARC deterministic, the compiler has to assume a lot of things so certain behaviours that were okay before are made illegal in ARC to ensure that the behaviour is consistent.

And this response seems to be from one of the Apple developers:

Our reasoning was split about 50/50 between (1) needing to be more careful about types and ownership and (2) wanting to eliminate an embarrassing wart in the language (not being allowed to complain about completely unknown methods with anything more strenuous than a warning). There is really no legitimate reason to call a method that's not even declared somewhere. The ability to do this makes some really trivial bugs (e.g. typos in selectors) runtime failures instead of compile failures. We have always warned about it. Fix your code.

So the main argument is that the compiler needs to know the ownership of the return value.

查看更多
登录 后发表回答