标签: objective-c-runtime

从Objective-C块创建IMP

IMPObjective-C中的类型表示函数指针,据我所知.有没有办法IMP从块指针创建一个?谢谢你的想法.

cocoa objective-c objective-c-runtime osx-snow-leopard objective-c-blocks

19
推荐指数
2
解决办法
5711
查看次数

NSProxy vs NSObject

我正在使用方法调配来在一个具有一些额外功能的类中包装所有方法调用.具体来说我是:

  • 检查此方法调用所需的对象是否在缓存中
  • 如果缓存有该对象返回它.
  • 如果没有,则调度到原始实现,填充缓存并返回该缓存.

对于每种方法,我都会重新路由到一个建议的方法.并使用+(BOOL)resolveInstanceMethod:(SEL)sel和IMP_implementationWithBlock实现新方法.

它工作正常,但代码没有很好地阅读.似乎NSProxy将提供一种更简洁的方式来实现此功能.

但还有另一种选择,就是简单地在我的目标对象的方法周围使用NSObject子类替换和拦截方法.通过重写forwardInvocation和methodSignatureForSelector,我可以获得所需的结果.

那么NSProxy给我的是什么?我为什么要用这个呢?

objective-c objective-c-runtime

19
推荐指数
1
解决办法
3337
查看次数

在NSString的isa指针上使用"setValue:forKey:"然后调用[string class]时出错

Heres是我得到的错误.

libobjc.A.dylib`_objc_trap():
0x14c13f4:  pushl  %ebp
0x14c13f5:  movl   %esp, %ebp
0x14c13f7:  ud2    
Run Code Online (Sandbox Code Playgroud)

所以基本上我试图理解如何NSString工作并试图找到一种方法来改变指向"真(char*)字符串"的指针,这被称为常量.

所以,我发现有一个名为isa的指针指向(__NSCFConstantString *).它让我想到,如果我改变那个指针,那么我可以改变字符串.

我试过的代码是这样的:

NSString *st3 = [[NSString alloc] initWithString:@"hihi"];
[st3 setValue:@"change" forKey:@"isa"];
Run Code Online (Sandbox Code Playgroud)

并且,结果表明

之前:

在此输入图像描述

后:

在此输入图像描述

它似乎改变了,但它改变了每个NSString具有@"hihi"字符串的对象.

然后我做的是[st3 class]希望它会给出isa指针然后我在顶部发布了错误消息.

你能解释一下发生了什么以及为什么会这样吗?而且,有没有办法实习(我不太确定这个术语)就像在Java中一样?

请避免说只使用"NSMutableString"我只是想弄清楚是否可能有某种方法可以做到这一点.

objective-c objective-c-runtime nsstring

19
推荐指数
1
解决办法
1042
查看次数

如何在NSOperation中实现NSRunLoop

我发布这个问题,因为我看到很多关于这个主题的混淆,我花了几个小时调试NSOperation子类作为结果.

问题是,当您执行异步方法时,NSOperation对您没有多大帮助,这些异步方法在异步回调完成之前实际上并不完整.

如果NSOperation本身是回调委托,由于在不同的线程上发生回调,它甚至可能不足以正确完成操作.

假设您在主线程中并创建了一个NSOperation并将其添加到NSOperationQueue,NSOperation中的代码会触发异步调用,该调用将调用AppDelegate或视图控制器上的某些方法.

您无法阻止主线程或UI将锁定,因此您有两个选项.

1)创建一个NSOperation并使用以下签名将其添加到NSOperationQueue:

[NSOperationQueue addOperations:@ [myOp] waitUntilFinished:?]

祝你好运.异步操作通常需要一个runloop,因此它不会工作,除非你继承NSOperation或使用一个块,但是如果你必须通过在回调完成时告诉它来"完成"NSOperation,那么即使一个块也不会工作.

所以......你用类似于下面的东西对NSOperation进行子类化,这样回调可以告诉操作何时完成:

//you create an NSOperation subclass it includes a main method that
//keeps the runloop going as follows
//your NSOperation subclass has a BOOL field called "complete"

-(void) main
{

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    //I do some stuff which has async callbacks to the appDelegate or any other class (very common)

    while (!complete && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

}

//I also have a setter that the …
Run Code Online (Sandbox Code Playgroud)

objective-c objective-c-runtime ios objective-c-blocks

18
推荐指数
2
解决办法
6498
查看次数

在Xcode 7中更改了+加载方法顺序

我发现Xcode 7(版本7.0(7A220))改变了+load在单元测试期间调用类和类别的方法的顺序.

如果属于测试目标的类别实现了一个+load方法,那么现在可以在最后调用它,此时类的实例可能已经被创建和使用.

我有一个AppDelegate实现+load方法.该AppDelegate.m文件还包含AppDelegate (MainModule)类别.此外,还有一个单元测试文件LoadMethodTestTests.m,其中包含另一个类别 - AppDelegate (UnitTest).

这两个类别也实现了+load方法.第一类属于主要目标,第二类属于测试目标.

我做了一个小测试项目来证明这个问题.它是一个空的默认Xcode一个视图项目,只更改了两个文件.

AppDelegate.m:

#import "AppDelegate.h"

@implementation AppDelegate

+(void)load {
    NSLog(@"Class load");
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSLog(@"didFinishLaunchingWithOptions");

    return YES;
}

@end

@interface AppDelegate (MainModule)
@end

@implementation AppDelegate (MainModule)

+(void)load {
    NSLog(@"Main Module +load");
}

@end
Run Code Online (Sandbox Code Playgroud)

和一个单元测试文件(LoadMethodTestTests.m):

#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "AppDelegate.h"

@interface LoadMethodTestTests : XCTestCase

@end

@interface AppDelegate (UnitTest) …
Run Code Online (Sandbox Code Playgroud)

unit-testing objective-c objective-c-runtime ios xcode7

18
推荐指数
1
解决办法
1891
查看次数

在arc下使用objc_getClassList

有没有人设法在arc下使用objc_getClassList,而不是为有问题的文件关闭弧线?

基本问题是其中一个参数是一个C类的Class指针.

iphone objective-c-runtime ios automatic-ref-counting

17
推荐指数
1
解决办法
3407
查看次数

为什么必须动态分配Objective-C对象?

为什么必须动态分配Objective-c对象?为什么我必须使它成为指向对象的指针,与C++不同,我可以在堆栈上创建它们?谢谢.

cocoa objective-c-runtime foundation static-allocation dynamic-allocation

16
推荐指数
1
解决办法
3208
查看次数

如何动态添加类方法?

使用Objective-C Runtime,如何将方法添加+layerClass到私有UIGroupTableViewCellBackground类(而不是其超类UIView)?注意:这仅用于测试(查看如何UITableViewStyleGrouped设置单元格backgroundView&selectedBackgroundView).

objective-c objective-c-runtime

16
推荐指数
1
解决办法
4814
查看次数

为什么类NSObject上的某些方法(-retainWeakReference,-allowsWeakReference,+ load,+ initialize)不能在运行时添加到其他类?

它是在运行时简单的创建副本MyNSObject中的 NSObject的:

首先,创建一个新的类对.

Class MyNSObject = objc_allocateClassPair(nil, "MyNSObject", 0);
Run Code Online (Sandbox Code Playgroud)

第二步从NSObject读取方法,协议和ivars ,并将它们添加到新类中.

uint instanceMethodCount;
Method *instanceMethodArray = class_copyMethodList([NSObject class], &instanceMethodCount);
for (int i = 0; i < instanceMethodCount; i++) {
    Method method = *(instanceMethodArray + i);
    SEL selector =  method_getName(method);
    IMP implementation = method_getImplementation(method);
    const char *types = method_getTypeEncoding(method);
    BOOL success = class_addMethod(MyNSObject, selector, implementation, types);
}
free(instanceMethodArray);

uint protocolCount;
Protocol **protocolArray = class_copyProtocolList([NSObject class], &protocolCount);
for (int i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

objective-c objective-c-runtime

14
推荐指数
1
解决办法
1390
查看次数

如何创建NSBlock对象?

我将在这个问题的前言中说明我要问的是教育和可能的调试目的.

如何在Objective C运行时内部创建块对象?

我看到所有类代表各种块类型的类的层次结构,下面的层次结构中最高的超类NSObjectNSBlock.倾销类的数据显示,它实现了+ alloc,+ allocWithZone:,+ copy+ copyWithZone:方法.其他块子类都没有实现这些类方法,这使我相信(可能是错误的NSBlock)负责块处理.

但是这些方法似乎在一个块的生命周期中的任何时候都不会被调用.我用自己的实现交换了实现并在每个实例中放置了一个断点,但是它们永远不会被调用.用NSObject实现做类似的练习给了我我想要的东西.

所以我假设块以不同的方式实现?任何人都可以了解这种实施方式的工作原理?即使我不能挂钩分配和复制块,我想了解内部实现.

objective-c objective-c-runtime objective-c-blocks

14
推荐指数
2
解决办法
3001
查看次数