iOS开发-黑魔法 method swizzle(一)

使用案例: 当需要在控制器销毁时,打印控制器的相关信息,需要在deallc 中写NSLog(@"....");  如果控制器非常多的时候,在每个控制器中都重写dealloc方法就显得很蛋疼

所以这时就需要runtime的一个方法: method_exchangeImplementations(Method m1, Method m2)

建一个UIViewController的类扩展:UIViewController+Extension

在这里,可以在下列两个方法

+ (void)load;
+ (void)initialize;
任意一个方法中添加下面的代码

 Method method1 = class_getInstanceMethod([XMGPerson class], @selector(dealloc));
 Method method2 = class_getInstanceMethod([XMGPerson class], @selector(myDealloc));
 method_exchangeImplementations(method1, method2);

但出现了这种错误,这是因为dealloc方法比较特殊:


但可以用下面方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Vulkan在桌面写字的代码示例: ```c #define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> #include <vulkan/vulkan.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义窗口宽度和高度 const uint32_t WIDTH = 800; const uint32_t HEIGHT = 600; // 定义顶点数据 const float vertices[] = { -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, 0.5f, 0.0f, 1.0f }; // 定义顶点索引 const uint16_t indices[] = { 0, 1, 2, 2, 3, 0 }; int main() { // 初始化GLFW库 if (!glfwInit()) { printf("Failed to initialize GLFW\n"); return -1; } // 创建GLFW窗口 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", NULL, NULL); // 创建Vulkan实例 VkInstance instance; VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Vulkan Example"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); createInfo.enabledExtensionCount = glfwExtensionCount; createInfo.ppEnabledExtensionNames = glfwExtensions; createInfo.enabledLayerCount = 0; if (vkCreateInstance(&createInfo, NULL, &instance) != VK_SUCCESS) { printf("Failed to create Vulkan instance\n"); return -1; } // 创建Vulkan设备 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, NULL); if (deviceCount == 0) { printf("Failed to find Vulkan physical device\n"); return -1; } VkPhysicalDevice* devices = (VkPhysicalDevice*)malloc(deviceCount * sizeof(VkPhysicalDevice)); vkEnumeratePhysicalDevices(instance, &deviceCount, devices); for (uint32_t i = 0; i < deviceCount; i++) { VkPhysicalDeviceProperties deviceProperties; vkGetPhysicalDeviceProperties(devices[i], &deviceProperties); if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { physicalDevice = devices[i]; break; } } if (physicalDevice == VK_NULL_HANDLE) { physicalDevice = devices[0]; } free(devices); float queuePriority = 1.0f; VkDeviceQueueCreateInfo queueCreateInfo = {}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = 0; queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = &queuePriority; VkDeviceCreateInfo deviceCreateInfo = {}; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; deviceCreateInfo.enabledExtensionCount = 0; deviceCreateInfo.ppEnabledExtensionNames = NULL; deviceCreateInfo.enabledLayerCount = 0; deviceCreateInfo.ppEnabledLayerNames = NULL; VkDevice device; if (vkCreateDevice(physicalDevice, &deviceCreateInfo, NULL, &device) != VK_SUCCESS) { printf("Failed to create Vulkan device\n"); return -1; } // 创建Vulkan交换链 VkSurfaceKHR surface; if (glfwCreateWindowSurface(instance, window, NULL, &surface) != VK_SUCCESS) { printf("Failed to create Vulkan window surface\n"); return -1; } uint32_t formatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, NULL); VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formats); VkSurfaceFormatKHR surfaceFormat; if (formatCount == 1 && formats[0].format == VK_FORMAT_UNDEFINED) { surfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; surfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; } else { for (uint32_t i = 0; i < formatCount; i++) { if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM) { surfaceFormat = formats[i]; break; } } } free(formats); VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; uint32_t presentModeCount = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL); VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(presentModeCount * sizeof(VkPresentModeKHR)); vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes); for (uint32_t i = 0; i < presentModeCount; i++) { if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { presentMode = presentModes[i]; break; } } free(presentModes); VkSurfaceCapabilitiesKHR surfaceCapabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfaceCapabilities); uint32_t imageCount = surfaceCapabilities.minImageCount + 1; if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) { imageCount = surfaceCapabilities.maxImageCount; } VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; swapchainCreateInfo.surface = surface; swapchainCreateInfo.minImageCount = imageCount; swapchainCreateInfo.imageFormat = surfaceFormat.format; swapchainCreateInfo.imageColorSpace = surfaceFormat.colorSpace; swapchainCreateInfo.imageExtent = { WIDTH, HEIGHT }; swapchainCreateInfo.imageArrayLayers = 1; swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; swapchainCreateInfo.preTransform = surfaceCapabilities.currentTransform; swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchainCreateInfo.presentMode = presentMode; swapchainCreateInfo.clipped = VK_TRUE; VkSwapchainKHR swapchain; if (vkCreateSwapchainKHR(device, &swapchainCreateInfo, NULL, &swapchain) != VK_SUCCESS) { printf("Failed to create Vulkan swapchain\n"); return -1; } uint32_t swapchainImageCount = 0; vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, NULL); VkImage* swapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage)); vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, swapchainImages); // 创建Vulkan渲染通道 VkRenderPass renderPass; VkAttachmentDescription attachmentDescription = {}; attachmentDescription.format = surfaceFormat.format; attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT; attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentReference attachmentReference = {}; attachmentReference.attachment = 0; attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkSubpassDescription subpassDescription = {}; subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpassDescription.colorAttachmentCount = 1; subpassDescription.pColorAttachments = &attachmentReference; VkRenderPassCreateInfo renderPassCreateInfo = {}; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassCreateInfo.attachmentCount = 1; renderPassCreateInfo.pAttachments = &attachmentDescription; renderPassCreateInfo.subpassCount = 1; renderPassCreateInfo.pSubpasses = &subpassDescription; if (vkCreateRenderPass(device, &renderPassCreateInfo, NULL, &renderPass) != VK_SUCCESS) { printf("Failed to create Vulkan render pass\n"); return -1; } // 创建Vulkan管线布局 VkPipelineLayout pipelineLayout; VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {}; pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutCreateInfo.setLayoutCount = 0; pipelineLayoutCreateInfo.pSetLayouts = NULL; pipelineLayoutCreateInfo.pushConstantRangeCount = 0; pipelineLayoutCreateInfo.pPushConstantRanges = NULL; if (vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, NULL, &pipelineLayout) != VK_SUCCESS) { printf("Failed to create Vulkan pipeline layout\n"); return -1; } // 创建Vulkan图形管线 VkShaderModule vertexShaderModule; VkShaderModuleCreateInfo vertexShaderModuleCreateInfo = {}; vertexShaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; vertexShaderModuleCreateInfo.codeSize = sizeof(uint32_t) * 4; vertexShaderModuleCreateInfo.pCode = (const uint32_t*)vertices; if (vkCreateShaderModule(device, &vertexShaderModuleCreateInfo, NULL, &vertexShaderModule) != VK_SUCCESS) { printf("Failed to create Vulkan vertex shader module\n"); return -1; } VkShaderModule fragmentShaderModule; VkShaderModuleCreateInfo fragmentShaderModuleCreateInfo = {}; fragmentShaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; fragmentShaderModuleCreateInfo.codeSize = sizeof(uint32_t) * 4; fragmentShaderModuleCreateInfo.pCode = (const uint32_t*)vertices; if (vkCreateShaderModule(device, &fragmentShaderModuleCreateInfo, NULL, &fragmentShaderModule) != VK_SUCCESS) { printf("Failed to create Vulkan fragment shader module\n"); return -1; } VkPipelineShaderStageCreateInfo vertexShaderStageCreateInfo = {}; vertexShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertexShaderStageCreateInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertexShaderStageCreateInfo.module = vertexShaderModule; vertexShaderStageCreateInfo.pName = "main"; VkPipelineShaderStageCreateInfo fragmentShaderStageCreateInfo = {}; fragmentShaderStageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; fragmentShaderStageCreateInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fragmentShaderStageCreateInfo.module = fragmentShaderModule; fragmentShaderStageCreateInfo.pName = "main"; VkPipelineShaderStageCreateInfo shaderStages[] = { vertexShaderStageCreateInfo, fragmentShaderStageCreateInfo }; VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {}; vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputStateCreateInfo.vertexBindingDescriptionCount = 0; vertexInputStateCreateInfo.pVertexBindingDescriptions = NULL; vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 0; vertexInputStateCreateInfo.pVertexAttributeDescriptions = NULL; VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {}; inputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssemblyStateCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; inputAssemblyStateCreateInfo.primitiveRestartEnable = VK_FALSE; VkViewport viewport = {}; viewport.x = 0.0f; viewport.y = 0.0f; viewport.width = (float)WIDTH; viewport.height = (float)HEIGHT; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor = {}; scissor.offset = { 0, 0 }; scissor.extent = { WIDTH, HEIGHT }; VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {}; viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportStateCreateInfo.viewportCount = 1; viewportStateCreateInfo.pViewports = &viewport; viewportStateCreateInfo.scissorCount = 1; viewportStateCreateInfo.pScissors = &scissor; VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {}; rasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizationStateCreateInfo.depthClampEnable = VK_FALSE; rasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE; rasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL; rasterizationStateCreateInfo.cullMode = VK_CULL_MODE_BACK_BIT; rasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizationStateCreateInfo.depthBiasEnable = VK_FALSE; rasterizationStateCreateInfo.lineWidth = 1.0f; VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {}; multisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampleStateCreateInfo.sampleShadingEnable = VK_FALSE; multisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {}; colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; colorBlendAttachmentState.blendEnable = VK_FALSE; VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {}; colorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlendStateCreateInfo.logicOpEnable = VK_FALSE; colorBlendStateCreateInfo.attachmentCount = 1; colorBlendStateCreateInfo.pAttachments = &colorBlendAttachmentState; VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_LINE_WIDTH }; VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {}; dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicStateCreateInfo.dynamicStateCount = 2; dynamicStateCreateInfo.pDynamicStates = dynamicStates; VkGraphicsPipelineCreateInfo pipelineCreateInfo = {}; pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineCreateInfo.stageCount = 2; pipelineCreateInfo.pStages = shaderStages; pipelineCreateInfo.pVertexInputState = &vertexInputStateCreateInfo; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCreateInfo; pipelineCreateInfo.pViewportState = &viewportStateCreateInfo; pipelineCreateInfo.pRasterizationState = &rasterizationStateCreateInfo; pipelineCreateInfo.pMultisampleState = &multisampleStateCreateInfo; pipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo; pipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo; pipelineCreateInfo.layout = pipelineLayout; pipelineCreateInfo.renderPass = renderPass; pipelineCreateInfo.subpass = 0; VkPipeline pipeline; if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &pipeline) != VK_SUCCESS) { printf("Failed to create Vulkan graphics pipeline\n"); return -1; } vkDestroyShaderModule(device, vertexShaderModule, NULL); vkDestroyShaderModule(device, fragmentShaderModule, NULL); // 创建Vulkan帧缓冲 VkImageView* swapchainImageViews = (VkImageView*)malloc(swapchainImageCount * sizeof(VkImageView)); for (uint32_t i = 0; i < swapchainImageCount; i++) { VkImageViewCreateInfo imageViewCreateInfo = {}; imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; imageViewCreateInfo.image = swapchainImages[i]; imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; imageViewCreateInfo.format = surfaceFormat.format; imageViewCreateInfo.components = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }; imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageViewCreateInfo.subresourceRange.baseMipLevel = 0; imageViewCreateInfo.subresourceRange.levelCount = 1; imageViewCreateInfo.subresourceRange.baseArrayLayer = 0; imageViewCreateInfo.subresourceRange.layerCount = 1; if (vkCreateImageView(device, &imageViewCreateInfo, NULL, &swapchainImageViews[i]) != VK_SUCCESS) { printf("Failed to create Vulkan image view\n"); return -1; } } VkFramebuffer* framebuffers = (VkFramebuffer*)malloc(swapchainImageCount * sizeof(VkFramebuffer)); for (uint32_t i = 0; i < swapchainImageCount; i++) { VkFramebufferCreateInfo framebufferCreateInfo = {}; framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferCreateInfo.renderPass = renderPass; framebufferCreateInfo.attachmentCount = 1; framebufferCreateInfo.pAttachments = &swapchainImageViews[i]; framebufferCreateInfo.width = WIDTH; framebufferCreateInfo.height = HEIGHT; framebufferCreateInfo.layers = 1; if (vkCreateFramebuffer(device, &framebufferCreateInfo, NULL, &framebuffers[i]) != VK_SUCCESS) { printf("Failed to create Vulkan framebuffer\n"); return -1; } } // 创建Vulkan命令池 VkCommandPool commandPool; VkCommandPoolCreateInfo commandPoolCreateInfo = {}; commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; commandPoolCreateInfo

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值