`
lizaochengwen
  • 浏览: 667285 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在object-c运行时替换私有类的方法

 
阅读更多
ios 有很多私有的类和函数,令人忧伤的是这些官方都不给用,对于一个开发者来说这是相当纠结的一件事。但如果你知道这个私有方法怎么实现的话呢?完全可以自己改写这些私有类和方法,下面以改写UIVebView这个类的一些方法作为例子来说明一下。

UIWebView 了view结构大概如下:

UIWebView:

  _UIWebViewScrollView(其实是scrollview)

  多个UIImageView

  UIWebBrowserView:

    UIWebBrowserViewMinusAccessoryView

 

 UIWebBrowserView 和 _UIWebViewScrollView都是我们不是能直接用的类,UIWebBrowserView下的UIWebBrowserViewMinusAccessoryView直接


的控制着webkit键盘的inputAccessoryView,即图中键盘上面这一栏。假设我们要去掉webkit键盘上面这一栏,自定义为我们自己的样式,应该怎么做呢?




首先要我们要在uiwebview对象中找到UIWebBrowserView的对象,直接遍历就Ok


1 /**
 2   * 找到UIWebBrowserView的对象
 3  */
 4 UIView *browserView = nil;
 5 for (UIView *subview in [[self.subviewsobjectAtIndex:0] subviews]) {
 6      if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) {
 7          browserView = subview;
 8           break;
 9       }
10 } 
11 // 拷贝 browserView 中的UIWebBrowserViewMinusAccessoryView
12 Class newClass = objc_duplicateClass(browserView, "UIWebBrowserViewMinusAccessoryView", 0);
13 
14 // 编写自己的实现方法accessoryViewImp
15 IMP accessoryViewImp = [self methodForSelector:@selector(emptyInputAccessoryView)];
16 
17 // 替换系统的inputAccessoryView方法 ,@@: 是type coding ,下面会讲到
18  class_replaceMethod(newClass, @selector(inputAccessoryView), accessoryViewImp, "@@:");
19 
20 //注册类
21 objc_registerClassPair(newClass);
22 
23 //重新设计browserView对象的类
24 object_setClass(browserView, newClass);
25 
26 //载入自己的inputAccessoryView
27 [browserView reloadInputViews];




一个Object-c的方法实现类型IMP 至少有两个参数self 和 _cmd,如下


1 // IMP 类型的自定义方法
2 id emptyInputAccessoryView(id self  , SEL _cmd /*, NSString *str 你的其它参数   */)
3 {  
4        UIView *view = [[[UIView alloc] init] autorelease];
5        //自定义你自己的view  
6        return view;
7 }




class_replaceMethod方法的最后一个参数是 type encodings ,用来标识IMP函数实现的返回值与参数,其中,

第一个字段@表示返回值是id类型

第二个字段@表示self参数

第三个字段:表示_cmd参数

第四个字段开始为用户定义的参数类型对应的encodings。

具体的type encodings 可以参考apple官方提供的 type encodings 对应表:

Code   Meaning

c         A char

i         An int

s        A short

l         A long
          l is treated as a 32-bit quantity on 64-bit programs.

q        A long long

C       An unsigned char

I        An unsigned int

S       An unsigned short

L       An unsigned long

Q      An unsigned long long

f       A float

d      A double

B      A C++ bool or a C99 _Bool

v      A void

*      A character string (char *)

@      An object (whether statically typed or typed id)

#       A class object (Class)

:        A method selector (SEL)

[array type]          An array

{name=type...}     A structure

(name=type...)     A union

bnum                   A bit field of num bits

^type                   A pointer to type

?                          An unknown type (among other things, this code is used for function pointers)
分享到:
评论

相关推荐

    object-c基础教程移动版2.pdf

    这在运行时可以用来替换或修改另一个类的行为。 13. Protocols(协议): 在Objective-C中,协议用于声明一组方法,但不实现它们。任何遵循该协议的类都必须实现这些方法。这类似于其他语言中的接口。 14. 内存管理...

    object-c基础教程.

    6. 访问权限:在Objective-C中,类的成员变量和方法可以有不同的访问级别,例如私有(private)和公共(public)。 7. 类级别的访问:指的是类本身对某些成员的访问权限。 8. 异常处理:Objective-C提供了对异常...

    IOS Object-C 中Runtime详解及实例代码

    这在动态添加或替换方法时非常有用。 5. **获取成员变量(Accessing Instance Variables)** `class_copyIvarList`函数提供成员变量的列表,`ivar_getName`用于获取成员变量的名称。这对于处理私有变量或在不使用...

    object c语法总结

    - **private**:私有方法,只能在当前类中访问。 - **protected**:受保护的方法,当前类及其子类都可以访问。 #### 属性与构造函数 - **属性**:用于简化对象属性的读取和设置操作。 - **构造函数**:用于初始化...

    iOS开发Runtime的用法

    Runtime,全称为Objective-C Runtime,是Objective-C语言的核心组成部分,它在程序执行过程中提供了对类、对象、方法等元数据的访问和操作能力。下面将详细介绍Runtime的几个关键概念和用法。 1. **消息传递...

    个人笔记--JAVA基础

    - 局部变量定义在方法中,仅在该方法的作用域内有效。 - **3.1.6. 构造方法** - 特殊的方法,用于初始化对象的状态。 - **3.1.7. 方法重载** - 同一个类中可以有多个同名方法,只要它们的参数列表不同即可。 -...

    iOS Runtime Demo

    通过Runtime,开发者可以在运行时动态创建类、修改方法、交换方法实现、获取对象属性等。 二、Runtime的主要功能 1. 动态类型:Objective-C中的所有对象在编译时并不确定其实际类型,而是在运行时决定。 2. 消息...

    Java经典问题答案(带书签).pdf

    - `throws`用于在方法签名中声明可能抛出的异常。 **Final, Finally和Finalize的区别** - `final`用于声明不可变的变量、方法或类。 - `finally`用于确保在try-catch语句块中总会执行的代码块。 - `finalize`是...

    Java Core课后习题.docx

    - `Teacher` 类同样包含一个构造方法,在创建 `Teacher` 对象时首先调用父类的构造方法,然后打印另一条消息。这里使用了 `super()` 调用了父类的构造方法。 程序运行结果为: - A. this is a Person - B. this is ...

    C#语言\C_基本语言及问题集锦

    - 在C#中,当你调用一个属性的`set`方法时,传递的隐含参数名称是`value`,其类型与该属性声明的类型相同。 #### 2. 实现继承 - C#中的继承通过在类定义后添加一个冒号(`:`)和基类的名称来实现。例如:`public ...

    java最新面试文档

    - 默认情况下,所有类继承自`Object`类,其`equals`方法默认行为与`==`相同。子类可以重写`equals`方法以提供更合理的比较逻辑。 #### 12. 静态变量和实例变量的区别 - **静态变量**(类变量):属于类本身,所有...

    C程序设计类与对象PPT学习教案.pptx

    【C程序设计】中的【类与对象】是面向对象编程的核心概念,主要涵盖以下几个关键知识点: 1. **面向对象程序设计概述**: - OOP(Object-Oriented Programming)是一种将现实世界问题转化为简单代码的编程范式,它...

    基于面向对象的c课件

    面向对象编程(Object-Oriented Programming,简称OOP)是一种流行的编程范式,它强调将数据和操作数据的方法封装在对象中,以实现模块化、可重用性和可维护性的程序设计。C语言,虽然最初设计时并不直接支持面向...

    豆瓣网C++研发工程师面试合集

    - 内联函数是在类的内部定义成员函数的函数体,这样的函数在函数调用的地方会在编译阶段进行代码替换,从而避免函数调用的开销,提高运行效率。 6. **this指针**: - 用途:成员函数通过`this`指针指向对象的首...

    swift-KVC与KVO使用姿势和原理解析

    其原理是通过ISA-swizzling(类指针替换)在运行时创建一个继承自原始类的新类,新类重写了被观察属性的setter方法,以触发通知。当属性值改变时,KVO会调用观察者的回调方法。 ### 应用场景 1. **数据绑定**:KVC...

    【05-面向对象(下)】

    加abstract修饰符,并把普通方法的方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号 即可。 抽象类的特征 •抽象类的特征:有得有失,得到了新能力,可以拥有抽象方法;失去了...

    Java经典面试题+答案(带书签)pdf

    - **宏**:预处理器的一种特性,常见于C/C++,用于在编译时替换文本。 **18. 0.01+0.09** - 浮点数运算可能会因为精度问题导致结果不准确。 - 在实际应用中,应考虑使用`BigDecimal`类进行精确计算。 **19. 类...

    Java极品学习资料

    - **普通代码块**:在方法调用时执行。 - 示例代码说明不同代码块的执行时机及其特点。 **可以调用私有构造方法吗** - 私有构造方法主要用于单例模式等场景。 - 示例代码说明如何间接调用私有构造方法。 **子类...

    java面试宝典

    写clone()方法时,通常都有一行代码,是什么?** 通常需要调用`super.clone()`方法来实现深复制。例如: ```java public Object clone() throws CloneNotSupportedException { return super.clone(); } ``` **...

    java 面试宝典

    其他类可以是任意访问级别的类,如默认访问级别(package-private)、私有类(private)等。 **2. Java有没有goto?** Java语言最初设计时包含了`goto`关键字,但在最终版本中将其移除,因此标准Java中并没有`goto`...

Global site tag (gtag.js) - Google Analytics