zoukankan      html  css  js  c++  java
  • implicitly declaring library function 'objc_msgSend'with type '(id,SEL,...)' 警告

    之前一直用objc_msgSend,但是没注意apple的文档提示,所以突然objc_msgSend crash了。
    
    之前32位的时候没问题,然后转换为64位之后就会发生EXC_BAD_ACCESS问题。
    
    当然apple再文档([64-Bit Transition Guide for Cocoa Touch中有](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html#//apple_ref/doc/uid/TP40013501-CH3-SW26))中也有提到:
    
    	Dispatch Objective-C Messages Using the Method Function’s Prototype
    	An exception to the casting rule described above is when you are calling the objc_msgSend function or any other similar functions in the Objective-C runtime that send messages. Although the prototype for the message functions has a variadic form, the method function that is called by the Objective-C runtime does not share the same prototype. The Objective-C runtime directly dispatches to the function that implements the method, so the calling conventions are mismatched, as described previously. Therefore you must cast the objc_msgSend function to a prototype that matches the method function being called.
    
    	Listing 2-14 shows the proper form for dispatching a message to an object using the low-level message functions. In this example, the doSomething: method takes a single parameter and does not have a variadic form. It casts the objc_msgSend function using the prototype of the method function. Note that a method function always takes an id variable and a selector as its first two parameters. After the objc_msgSend function is cast to a function pointer, the call is dispatched through that same function pointer
    
    你必须先定义原型才可以使用,这样才不会发生崩溃
    
    	id Fun(int x,id y,...);
    	id (*action)(int,id) = (id (*)(int,id)) Fun;
    	action(1,@"s");
    
    如果没有返回值id改为void
    
    原来我们这么写:
    
    	objc_msgSend(self,@selector(doSomething:), 0);
    按照apple的规范:
    
    	- (int) doSomething:(int) x { ... }
    	- (void) doSomethingElse {
        	int (*action)(id, SEL, int) = (int (*)(id, SEL, int)) objc_msgSend;
        	action(self, @selector(doSomething:), 0);
    	}
    
    最终简化之后64位调用:
    
    	((void(*)(id, SEL,int))objc_msgSend)(self, @selector(doSomething:), 0);

    原文:http://blog.iloss.me/post/kai-fa/2014-12-09-objc_msgsend?action=show_raw
  • 相关阅读:
    【leetcode】1630. Arithmetic Subarrays
    【leetcode】1629. Slowest Key
    【leetcode】1624. Largest Substring Between Two Equal Characters
    【leetcode】1620. Coordinate With Maximum Network Quality
    【leetcode】1619. Mean of Array After Removing Some Elements
    【leetcode】1609. Even Odd Tree
    【leetcode】1608. Special Array With X Elements Greater Than or Equal X
    【leetcode】1603. Design Parking System
    【leetcode】1598. Crawler Log Folder
    Java基础加强总结(三)——代理(Proxy)Java实现Ip代理池
  • 原文地址:https://www.cnblogs.com/daaiwusehng/p/5132826.html
Copyright © 2011-2022 走看看